Skip to main content
Glama
README.md
# 👁️ @fastcar/mcp-vision-tools

> 为 Coding Agent 提供看图、OCR、主体定位、视频抽帧分析,以及可选的图片生成与编辑能力。

`@fastcar/mcp-vision-tools` 是一个本地 MCP 服务。它把图片或视频帧交给 OpenAI Chat Completions 兼容的多模态模型,并将经过校验的结构化结果返回给 Codex、Claude Code、Kimi、Cursor 或其他 MCP 客户端。

生图能力是独立的可选模块:未配置生图 profile 时,不注册相关工具,也不影响视觉理解服务。

发布验证:[npm 包](https://www.npmjs.com/package/@fastcar/mcp-vision-tools) · [GitHub 源码](https://github.com/williamDazhangyu/-fastcar-mcp-vision-tools) · [问题反馈](https://github.com/williamDazhangyu/-fastcar-mcp-vision-tools/issues)。`@fastcar` 是 npm 发布 scope,源码由该 GitHub 仓库维护。

```text
图片 / 视频 / 生图指令
          │
          ▼
   Coding Agent / MCP Client
          │  MCP
          ▼
 @fastcar/mcp-vision-tools
    ├─ 视觉理解 → OpenAI-compatible Chat Completions
    └─ 图片生成 → OpenAI Images 或自定义 adapter
          │
          ▼
 结构化 JSON / 本地图片文件
```

## 🧭 导航

- [✨ 能力概览](#features)
- [⚡ 五分钟开始](#quick-start)
- [📦 安装与环境要求](#installation)
- [⌨️ CLI 命令](#cli)
- [⚙️ 模型配置](#configuration)
- [🔌 MCP 接入](#mcp-setup)
- [🧰 MCP 工具](#mcp-tools)
- [🎨 Image2 与自定义生图模型](#image-providers)
- [🌊 进度、兼容性与资源边界](#runtime-boundaries)
- [🩺 运维与诊断](#operations)
- [🔐 安全边界](#security)
- [🧩 Agent Skill](#agent-skill)
- [🛠️ 开发与发布](#development)

<a id="features"></a>
## ✨ 能力概览

| 能力 | 状态 | 说明 |
| --- | :---: | --- |
| 🖼️ 图片理解 | ✅ | 综合分析、OCR、摘要、主体定位 |
| 🎞️ 视频分析 | ✅ | 视频探测、均匀抽帧、多帧结构化理解 |
| 🧠 多模型 profile | ✅ | 添加、编辑、删除并切换默认视觉模型 |
| 🎨 图片生成 | 可选 | OpenAI Images 兼容的图片生成 |
| 🪄 图片编辑 | 可选 | 1–16 张参考图和可选 alpha 蒙版 |
| 🧱 自定义生图模型 | 可选 | 通过受信任的 ESM adapter 扩展非标准 Provider |
| 🌐 双传输 | ✅ | localhost Streamable HTTP 与 stdio MCP |
| 🔗 客户端配置 | ✅ | 自动检测并配置 Codex、Claude Code、Kimi、Cursor、DeepSeek Harness (dsh) |
| ⏳ 异步任务 | ✅ | 长时工具立即返回 taskId,以事件等待获取结果,支持恢复查询与取消 |
| 🛡️ 稳定性保护 | ✅ | 持久化终态、重启中断、超时、FIFO 队列、原子写入 |
| 🤖 Agent Skill | ✅ | 首次 CLI 运行时同步到用户级 Skill 目录 |

支持的媒体来源:

- 本地绝对路径或相对路径;
- `file:` URL;
- HTTP(S) URL,包括重定向后的资源。

<a id="quick-start"></a>
## ⚡ 五分钟开始

### 1. 安装

```bash
npm install -g @fastcar/mcp-vision-tools
```

确认 CLI:

```bash
mcp-vision-tools --version
mcp-vision-tools --help
```

### 2. 添加视觉模型

```bash
mcp-vision-tools config
```

也可以直接进入 profile 添加流程:

```bash
mcp-vision-tools models add
```

向导会安全收集 profile 名称、API Base URL、API key、模型名和超时时间。API key 输入不回显,不会出现在命令参数中。

### 3. 启动并接入客户端

```bash
mcp-vision-tools start
```

`start` 会:

1. 读取默认视觉模型;
2. 校验 Chat Completions 端点;
3. 在校验成功后替换旧 daemon;
4. 启动只监听 `127.0.0.1` 的 HTTP MCP;
5. 执行 MCP `initialize` 和 `tools/list`;
6. 更新已检测到的客户端注册。

成功后会返回实际地址,例如:

```text
http://127.0.0.1:32123/mcp
```

端口由服务选择并持久化。不要把示例端口手工写死到客户端配置中。

### 4. 检查状态

```bash
mcp-vision-tools status
mcp-vision-tools doctor
```

客户端注册更新后,通常需要重启客户端或创建新的 Agent 会话,才能重新发现 MCP 工具。

### 5. 可选:启用生图

```bash
mcp-vision-tools image-models add image2
mcp-vision-tools restart
```

没有生图配置时,只暴露视觉理解工具;增加或移除生图能力后,需要重启 daemon 或重新连接 stdio 会话。

<a id="installation"></a>
## 📦 安装与环境要求

### 环境要求

| 项目 | 要求 |
| --- | --- |
| Node.js | `>= 20.0.0` |
| 操作系统 | Windows、macOS、Linux |
| 视觉模型 | OpenAI Chat Completions 兼容,并支持图片输入 |
| 图片模型 | 可选;OpenAI Images 兼容或自定义 adapter |
| FFmpeg | 默认使用依赖中的 `ffmpeg-static` |

### 全局安装

```bash
npm install -g @fastcar/mcp-vision-tools
```

### 使用 npx

```bash
npx -y @fastcar/mcp-vision-tools --help
npx -y @fastcar/mcp-vision-tools stdio
```

### 无参数行为

- TTY 终端:打开交互菜单;
- 非 TTY / 管道环境:自动启动 stdio MCP。

普通终端管理建议显式使用 `status`、`start`、`doctor` 等子命令。

<a id="cli"></a>
## ⌨️ CLI 命令

### 命令总览

| 命令 | 作用 |
| --- | --- |
| `mcp-vision-tools` | TTY 中打开交互菜单;管道中启动 stdio MCP |
| `mcp-vision-tools stdio` | 显式启动 stdio MCP |
| `mcp-vision-tools config` | 打开视觉模型配置向导 |
| `mcp-vision-tools models list` | 列出视觉模型 profiles |
| `mcp-vision-tools models add [name]` | 添加视觉模型 profile |
| `mcp-vision-tools models edit [name]` | 编辑视觉模型 profile |
| `mcp-vision-tools models use <name>` | 设置默认视觉模型 |
| `mcp-vision-tools models remove <name>` | 删除视觉模型 |
| `mcp-vision-tools image-models list` | 列出生图 profiles、能力和默认项 |
| `mcp-vision-tools image-models add [name]` | 添加生图 profile |
| `mcp-vision-tools image-models edit [name]` | 编辑生图 profile |
| `mcp-vision-tools image-models use <name> [generate\|edit\|both]` | 设置分操作默认生图 profile |
| `mcp-vision-tools image-models remove <name>` | 删除生图 profile |
| `mcp-vision-tools artifacts status [directory]` | 统计托管或指定目录中的生图产物 |
| `mcp-vision-tools artifacts cleanup [directory]` | 清理超过保留期的生图产物 |
| `mcp-vision-tools artifacts cleanup [directory] --all` | 删除目录中全部由本工具命名的生图产物 |
| `mcp-vision-tools start` | 校验视觉端点;首次交互启动用复选框选择客户端,之后只刷新已选择客户端 |
| `mcp-vision-tools restart` | 重新执行完整启动流程;首次交互启动用复选框选择客户端 |
| `mcp-vision-tools start --daemon-only` | 启动 daemon,不修改客户端配置 |
| `mcp-vision-tools restart --daemon-only` | 重启 daemon,不修改客户端配置 |
| `mcp-vision-tools stop` | 无活动任务时停止 daemon |
| `mcp-vision-tools start\|restart\|stop --force` | 强制中断活动任务后执行;仅限用户明确授权 |
| `mcp-vision-tools status` | 查看 daemon 状态和 MCP URL |
| `mcp-vision-tools logs [lines]` | 查看 daemon 日志,默认 80 行 |
| `mcp-vision-tools setup` | 启动或复用 HTTP daemon,并配置客户端 |
| `mcp-vision-tools setup stdio` | 将客户端配置为 stdio transport |
| `mcp-vision-tools clients configure` | 通过复选框重新选择并更新客户端注册 |
| `mcp-vision-tools clients remove [client]` | 移除单个客户端的 fastcar-vision MCP;无参数时显示选择项 |
| `mcp-vision-tools doctor` | 执行配置、端点、daemon、MCP、Skill 和客户端诊断 |
| `mcp-vision-tools skill status` | 检查用户级 Agent Skill |
| `mcp-vision-tools skill sync` | 启用并同步 Agent Skill |
| `mcp-vision-tools skill uninstall` | 删除并持久禁用 Agent Skill |
| `mcp-vision-tools --help` | 显示帮助 |
| `mcp-vision-tools --version` | 显示版本 |

### Agent 与 JSON 模式

管理命令可附加:

```bash
mcp-vision-tools doctor --agent --json
mcp-vision-tools status --agent --json
mcp-vision-tools models list --agent --json
mcp-vision-tools image-models list --agent --json
mcp-vision-tools artifacts status --agent --json
```

- `--agent` 自动启用单行稳定 JSON;
- `--json` 启用 JSON 输出;
- `models add/edit`、`image-models add/edit` 和 `config` 需要安全交互输入,因此拒绝 `--agent`。

<a id="configuration"></a>
## ⚙️ 模型配置

视觉理解和图片生成使用两个相互独立的配置文件。建议始终通过 CLI 修改,避免手工处理 API key。

### 👁️ 视觉模型配置

默认文件:

```text
~/.mcp-vision-tools.json
```

```json
{
  "version": 1,
  "defaultProfile": "office-vl",
  "profiles": {
    "office-vl": {
      "baseUrl": "https://api.example.com/v1",
      "apiKey": "<YOUR_API_KEY>",
      "model": "qwen2.5-vl",
      "timeoutMs": 120000
    }
  },
  "defaultFrames": 6,
  "ffmpegPath": "C:/tools/ffmpeg/bin/ffmpeg.exe",
  "clientSetup": {
    "selected": ["dsh"]
  }
}
```

`clientSetup.selected` 控制启动时自动维护哪些客户端。首次交互式 `start` 或 `restart` 会显示复选框,默认勾选 dsh,其他未配置客户端默认不勾选;已有注册会标记为“已配置”并保持勾选。取消勾选已有客户端后,程序会再次确认是否删除旧注册。选择结果会保存到该配置。非 TTY、`--agent`、`--json` 和 `--daemon-only` 启动不会弹窗,也不会自动修改客户端配置。显式 `setup` 会配置检测到的客户端并同步更新该选择。

视觉 profile 选择顺序:

```text
工具参数 profile
  → VISION_PROFILE
  → defaultProfile
  → "default"
```

只设置部分 `VISION_BASE_URL`、`VISION_API_KEY` 或 `VISION_MODEL` 时,会覆盖所选 profile 的对应字段,并保留其余存储字段。

旧版扁平配置会在读取时兼容为名为 `default` 的 profile:

```json
{
  "baseUrl": "https://api.example.com",
  "apiKey": "<YOUR_API_KEY>",
  "model": "vision-model"
}
```

### 🎨 生图模型配置

默认文件:

```text
~/.mcp-vision-tools.images.json
```

```json
{
  "version": 1,
  "defaults": {
    "generate": "image2",
    "edit": "image2"
  },
  "profiles": {
    "image2": {
      "baseUrl": "https://api.example.com/v1",
      "apiKey": "<YOUR_IMAGE_API_KEY>",
      "model": "gpt-image-2",
      "timeoutMs": 300000,
      "operations": ["generate", "edit"],
      "adapter": {
        "kind": "openai-images"
      }
    }
  }
}
```

生图配置规则:

- `operations` 必须是非空的 `generate`、`edit` 或两者;
- `defaults.generate` 与 `defaults.edit` 可指向不同 profile;
- 默认项只能指向真实存在且支持对应操作的 profile;
- 环境变量可覆盖已有 profile;
- 完整的纯环境配置会创建一个仅在当前进程有效的 profile,名称来自 `VISION_IMAGE_PROFILE`,未设置时为 `image2`;
- 不完整的纯环境配置和空的 `VISION_IMAGE_OPERATIONS` 会被拒绝;
- 列表、Doctor、工具注册和实际调用使用同一份有效配置;任何列表都不会返回 API key。

单次操作的 profile 选择顺序:

```text
工具参数 profile
  → 支持该操作的 VISION_IMAGE_PROFILE
  → 支持该操作的 defaults.generate / defaults.edit
  → 第一个支持该操作的有效 profile
```

### Profile 名称

profile 名称支持字母、数字、Unicode、点号、下划线和连字符,例如:

```text
office-vl
qwen2.5-vl
内部视觉模型
image2-prod
```

### URL 规范化

配置应填写 API 根地址或 `/v1` 地址,不要填写 `/chat/completions`。以下输入都会规范化为 `https://api.example.com/v1`:

```text
https://api.example.com
https://api.example.com/
https://api.example.com/v1
https://api.example.com/v1/chat/completions
```

### 配置写入保证

- 配置使用跨进程文件锁;
- 临时文件写入后原子替换;
- Windows 短暂的文件占用会有限重试;
- 锁包含唯一 token、PID 和创建时间;
- 配置损坏、schema 错误或权限失败不会被当成空配置覆盖;
- 并发 Agent 更新不会静默丢失正常写入。

### 环境变量

#### 视觉模型与媒体

| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `VISION_PROFILE` | 配置默认项 | 本次运行的视觉 profile |
| `VISION_BASE_URL` | profile 值 | 覆盖 API Base URL |
| `VISION_API_KEY` | profile 值 | 覆盖 API key |
| `VISION_MODEL` | profile 值 | 覆盖模型名 |
| `VISION_TIMEOUT_MS` | `120000` | 模型与媒体总超时,毫秒 |
| `VISION_FRAMES` | `6` | 视频默认抽帧数,最大 16 |
| `VISION_FFMPEG_PATH` | `ffmpeg-static` | 自定义 FFmpeg 路径 |
| `MCP_VISION_CONFIG` | `~/.mcp-vision-tools.json` | 视觉配置文件 |
| `MCP_VISION_STATE_DIR` | 平台状态目录 | daemon 与能力缓存目录 |

#### 生图模型

| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `MCP_VISION_IMAGE_CONFIG` | `~/.mcp-vision-tools.images.json` | 生图配置文件 |
| `VISION_IMAGE_PROFILE` | 分操作默认项 | 当前生图 profile |
| `VISION_IMAGE_BASE_URL` | profile 值 | 覆盖图片 API Base URL |
| `VISION_IMAGE_API_KEY` | profile 值 | 覆盖图片 API key |
| `VISION_IMAGE_MODEL` | profile 值 | 覆盖图片模型名 |
| `VISION_IMAGE_TIMEOUT_MS` | `300000` | 整次生图操作超时,毫秒 |
| `VISION_IMAGE_OPERATIONS` | 保留已有能力;纯环境配置默认两项 | 逗号分隔的 `generate,edit` |
| `VISION_IMAGE_ADAPTER_MODULE` | 内置 adapter | 自定义 `.mjs` / `.js` 绝对路径 |

#### 并发与队列

| 变量 | 自适应默认值 | 合法范围 |
| --- | --- | --- |
| `VISION_PROVIDER_CONCURRENCY` | `clamp(CPU × 2, 8, 16)` | 1–256 |
| `VISION_IMAGE_CONCURRENCY` | `clamp(ceil(CPU / 2), 2, 8)` | 1–256 |
| `VISION_VIDEO_CONCURRENCY` | `clamp(floor(CPU / 4), 1, 4)` | 1–256 |
| `VISION_ANALYSIS_QUEUE_LIMIT` | `min(providerConcurrency × 4, 64)` | 0–4096 |
| `VISION_GENERATION_CONCURRENCY` | `2` | 1–32 |
| `VISION_GENERATION_QUEUE_LIMIT` | `8` | 0–256 |

队列采用有界 FIFO。超过上限时新任务立即失败,不会无限占用内存;等待中的任务支持取消。

<a id="mcp-setup"></a>
## 🔌 MCP 接入

MCP server 信息:

```text
name: fastcar-vision
version: 0.1.1
```

### 推荐:localhost HTTP

```bash
mcp-vision-tools start
# 或仅做客户端配置
mcp-vision-tools setup
```

daemon 只监听 `127.0.0.1`:

| 路径 | 作用 |
| --- | --- |
| `/mcp` | Streamable HTTP MCP endpoint |
| `/health` | 实例身份与健康检查 |
| `/shutdown` | 使用内部随机 token 的关闭接口 |

### stdio

```bash
mcp-vision-tools stdio
```

stdio 模式下:

- `stdout` 仅输出 MCP JSON-RPC;
- 日志写入 `stderr`;
- 每个客户端进程拥有独立的 MCP server 生命周期。

### 自动配置客户端

```bash
mcp-vision-tools setup
mcp-vision-tools setup stdio
```

写入客户端配置前会先验证 MCP `initialize` 和 `tools/list`。验证失败时不会修改配置。

首次执行交互式 `start` 或 `restart` 时,会以复选框列出已检测到的客户端。默认只勾选 dsh,已有注册会标记并默认保留;取消已有客户端后会询问是否同时删除旧配置。后续启动只维护配置中 `clientSetup.selected` 的客户端。非首次需要调整客户端时执行:

```bash
mcp-vision-tools clients configure
```

该命令会复用同一组选项:已有注册默认勾选,新增客户端可以直接勾选,取消已有客户端后会确认是否删除旧注册,并只更新最终选中的客户端。已有 HTTP 注册会更新到当前 daemon URL,已有 stdio 注册会保留原 command/args;新客户端默认使用 HTTP。普通交互模式只显示简短的完成提示,不输出完整配置对象。需要移除某个客户端时执行:

```bash
mcp-vision-tools clients remove
```

交互终端会显示单选列表并要求确认。脚本可直接指定客户端并请求稳定 JSON:

```bash
mcp-vision-tools clients remove codex --agent --json
```

移除只删除 `fastcar-vision` 注册,不会影响同一客户端中的其他 MCP;重复移除是幂等的。

支持:

| 客户端 | HTTP | stdio | 配置方式 |
| --- | :---: | :---: | --- |
| Codex | ✅ | ✅ | 优先调用 `codex mcp` CLI |
| Claude Code | ✅ | ✅ | 优先调用 `claude mcp` CLI |
| Kimi | ✅ | ✅ | CLI 或原子合并 `~/.kimi-code/mcp.json` |
| Cursor | ✅ | ✅ | 原子合并 `~/.cursor/mcp.json` |
| DeepSeek Harness (dsh) | ✅ | ✅ | 原子合并 `~/.dsh/cordis.patch.yml`(或各 profile 的 `cordis.patch.yml`),注册 `@deepseek-ai/dsh-mcp-client` 插件 |

dsh 需要先单独安装并确保 `dsh --version` 可执行;`mcp-vision-tools setup` 只负责检测已有 dsh 并写入 MCP 配置,不会安装 dsh 本体。

手工配置 stdio 时可使用:

```bash
codex mcp add fastcar-vision -- mcp-vision-tools stdio
claude mcp add --scope user fastcar-vision -- mcp-vision-tools stdio
```

客户端配置安全保证:

- 子进程有超时和输出上限;
- 替换 CLI 注册前读取并解析旧注册;
- 新增失败时尝试恢复旧注册;
- JSON 配置保留其他 MCP server 和未知字段;
- 写入采用临时文件与原子替换;
- `doctor` 检查客户端是否精确指向当前 daemon URL。

<a id="mcp-tools"></a>
## 🧰 MCP 工具

### 工具注册条件

| 工具 | 注册条件 | 作用 |
| --- | --- | --- |
| `analyze_image` | 始终 | 提交图片理解、OCR、摘要和定位任务 |
| `analyze_video` | 始终 | 提交视频抽帧分析任务 |
| `list_vision_models` | 始终 | 列出视觉 profiles,不返回 API key |
| `get_vision_task` | 始终 | 立即查询任务,供断线恢复或人工检查 |
| `wait_vision_task` | 始终 | 事件驱动等待终态;完成即返回,超时返回精简心跳 |
| `cancel_vision_task` | 始终 | 幂等取消未完成任务 |
| `list_image_models` | 至少一个有效生图操作 | 列出生图 profiles,不返回 API key |
| `generate_image` | 至少一个 profile 支持 `generate` | 提交图片生成与保存任务 |
| `edit_image` | 至少一个 profile 支持 `edit` | 提交多参考图编辑与保存任务 |

### ⏳ 统一异步调用合同

`analyze_image`、`analyze_video`、`generate_image` 和 `edit_image` 都只负责受理任务,不等待 Provider 完成。成功受理后立即返回:

```json
{
  "taskId": "7db2c542-3f79-45e3-b470-4f23656610c4",
  "operation": "generate_image",
  "status": "queued",
  "createdAt": "2026-08-09T12:00:00.000Z",
  "terminal": false,
  "resultAvailable": false,
  "mayHaveIncurredCost": false,
  "retryPolicy": "not_applicable",
  "recommendedAction": "wait_vision_task"
}
```

调用方随后调用 `wait_vision_task`。服务端订阅任务终态事件,任务在等待窗口内完成时立即返回,不会固定等满 20 秒,也不会在内部每 5 秒轮询。

```json
{
  "taskId": "7db2c542-3f79-45e3-b470-4f23656610c4",
  "maxWaitMs": 20000
}
```

`maxWaitMs` 可取 `1000–25000`,默认 `20000`。如果任务仍未完成,工具只返回精简心跳:

```json
{
  "taskId": "7db2c542-3f79-45e3-b470-4f23656610c4",
  "operation": "generate_image",
  "status": "running",
  "progress": 46,
  "elapsedMs": 20431,
  "waitTimedOut": true,
  "terminal": false,
  "resultAvailable": false,
  "mayHaveIncurredCost": true,
  "retryPolicy": "not_applicable",
  "recommendedAction": "wait_vision_task"
}
```

收到 `waitTimedOut: true` 后,立即以同一 `taskId` 再调用 `wait_vision_task`。等待本身已经覆盖整个窗口,不需要再 sleep;不要重新提交原任务,也不要改用 `get_vision_task` 循环查询。短任务例如 6 秒完成,会在约 6 秒时返回;70 秒任务通常只需要约 4 次等待调用。

任务状态:

| status | 含义 | 是否终态 |
| --- | --- | :---: |
| `queued` | 已持久化,等待后台执行 | — |
| `running` | 正在准备媒体、调用 Provider 或保存结果 | — |
| `succeeded` | 已完成,权威结果位于 `result` | ✅ |
| `failed` | 执行失败,脱敏原因位于 `error` | ✅ |
| `cancelled` | 调用方显式取消 | ✅ |
| `interrupted` | daemon/stdio 进程在完成前关闭或重启 | ✅ |
| `not_found` | taskId 不存在或 24 小时元数据已过期 | ✅ |

每个响应都提供面向 Agent 的结构化决策字段:

| 字段 | 语义 |
| --- | --- |
| `terminal` | 是否已经进入终态;`false` 时继续等待 |
| `resultAvailable` | 是否存在可使用的权威 `result` |
| `mayHaveIncurredCost` | Provider 调用是否可能已经产生费用;这是保守提示,不是账单确认 |
| `retryPolicy` | `not_applicable`、`user_confirmation_required` 或 `do_not_retry` |
| `recommendedAction` | `wait_vision_task`、`use_result`、`report_result`、`ask_user_before_resubmit` 或 `report_terminal_state` |

`get_vision_task` 会立即返回完整的当前快照,包括运行中的 `progress`、截断后的 `message`、实时 `elapsedMs` 和时间戳。它只用于断线恢复、人工检查或确认未知 `taskId`,不是常规等待路径。业务失败、取消和中断是可读取的结构化终态,不应作为传输错误重试;未知 taskId 才返回 MCP `isError: true`。

如果工具在受理或查询阶段发生同步错误,会返回 `isError: true`,并同时提供文本内容和可机器读取的错误对象;消息会先清理凭据再截断:

```json
{
  "ok": false,
  "error": {
    "code": "TOOL_CALL_FAILED",
    "tool": "analyze_image",
    "message": "已脱敏的错误消息"
  }
}
```

长时任务已经成功受理后的 Provider 错误仍通过 `wait_vision_task` 的 `failed` 终态返回,不会被改写为同步工具错误。

Agent 必须遵守:

1. 提交长时工具并保存 `taskId`;
2. 优先调用 `wait_vision_task`,心跳超时后继续调用同一工具;
3. 仅把 `get_vision_task` 用于恢复或即时检查,不用它轮询;
4. 视觉分析成功时执行 `use_result`;生图或编辑成功时执行 `report_result`,直接报告 `result.images[].path`;
5. 生成后视觉复查是可选项。普通生成/编辑请求不授权 Agent 再调用 `analyze_image`、`view_image` 或其他看图工具;只有用户明确要求执行检查、比较、质量验证或迭代验收时才能复查。提示词中的风格、质量、构图或布局要求只是生成约束,不是复查授权;意图不明确时直接交付,不为自检额外询问;
6. `failed` 或 `interrupted` 时说明错误及可能成本,询问用户是否重新提交;得到明确确认前不得重提;
7. `cancelled` 或 `not_found` 时报告终态,不自动重试;
8. 只有用户明确要求时才调用 `cancel_vision_task`。

### 🖼️ `analyze_image`

| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | :---: | --- | --- |
| `image` | string | ✅ | — | 本地路径、`file:` URL 或 HTTP(S) URL |
| `instruction` | string | — | 按 intent 生成 | 补充分析指令 |
| `intent` | enum | — | `analyze` | `analyze`、`ocr`、`summarize`、`locate` |
| `imageMode` | enum | — | `auto` | `auto`、`fast`、`balanced`、`quality`、`original` |
| `reasoningEffort` | enum | — | `auto` | `auto`、`low`、`medium`、`high` |
| `profile` | string | — | 默认视觉 profile | 显式选择模型 |

```json
{
  "image": "D:/screenshots/error.png",
  "instruction": "识别报错并解释可能原因",
  "intent": "ocr",
  "imageMode": "quality",
  "reasoningEffort": "medium",
  "profile": "office-vl"
}
```

#### intent

| 值 | 输出要求 |
| --- | --- |
| `analyze` | `summary`、`details`、`ocr`、`regions` |
| `ocr` | `summary`、`ocr` |
| `summarize` | `summary` |
| `locate` | `summary`、`regions` |

调用方 Agent 决定 intent;服务不会覆盖显式选择。

#### imageMode

| 值 | 最长边目标 | 说明 |
| --- | ---: | --- |
| `auto` | 按 intent | 通用默认值 |
| `fast` | 1536 px | 快速预览和摘要 |
| `balanced` | 2048 px | 常规分析 |
| `quality` | 4096 px | OCR、小字和细节 |
| `original` | 不处理 | 保留原始字节 |

`auto` 策略:`summarize → 1536`、`ocr → 4096`、`locate → 2560`、`analyze → 2048`。处理过程不裁剪、不放大小图;没有缩放且重编码更大时继续使用原图。

#### reasoningEffort

`auto` 不发送 `reasoning_effort`。端点不支持显式推理程度时,服务会省略该字段重试,并在 metadata 中提供 warning。

推荐组合:

| 场景 | intent | imageMode | reasoningEffort |
| --- | --- | --- | --- |
| 快速看图 | `summarize` | `fast` | `low` |
| 常规分析 | `analyze` | `balanced` | `medium` |
| 小字 OCR | `ocr` | `quality` | `low` / `medium` |
| 主体定位 | `locate` | `balanced` | `medium` |
| 深度细节 | `analyze` | `quality` | `high` |

### 🎞️ `analyze_video`

| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | :---: | --- | --- |
| `video` | string | ✅ | — | 本地路径、`file:` URL 或 HTTP(S) URL |
| `instruction` | string | — | 视频综合分析提示 | 补充分析要求 |
| `frames` | integer | — | 配置值或 6 | 1–16 帧 |
| `profile` | string | — | 默认视觉 profile | 显式选择模型 |

处理流程:

1. 本地视频先做文件检查;远程视频流式写入唯一临时目录;
2. FFmpeg 验证视频轨道并探测时长;
3. 在完整时间轴上均匀选择采样点;
4. 抽取按时间排序的 JPEG 帧;
5. 一次性提交给多模态模型;
6. 使用真实帧标签校正 `samples[].source`;
7. 无论成功或失败都清理远程临时文件。

### 📋 `list_vision_models`

```json
{
  "defaultProfile": "office-vl",
  "profiles": [
    {
      "name": "office-vl",
      "model": "qwen2.5-vl",
      "baseUrl": "https://api.example.com/v1",
      "isDefault": true
    }
  ]
}
```

### 🎨 `generate_image`

| 参数 | 类型 | 必填 | 默认值 | 限制 |
| --- | --- | :---: | --- | --- |
| `prompt` | string | ✅ | — | 1–32000 字符 |
| `profile` | string | — | generate 默认项 | 必须支持 `generate` |
| `count` | integer | — | `1` | 1–4 |
| `size` | string | — | `auto` | `auto` 或 `WIDTHxHEIGHT`;边长不超过 16384 |
| `quality` | enum | — | `auto` | `auto`、`high`、`medium`、`low` |
| `outputDirectory` | string | — | 工具托管目录 | 相对路径基于服务进程 cwd |

### 🪄 `edit_image`

包含 `generate_image` 的全部参数,另外接受:

| 参数 | 类型 | 必填 | 限制 |
| --- | --- | :---: | --- |
| `images` | string[] | ✅ | 1–16 张本地、`file:` 或 HTTP(S) 参考图 |
| `mask` | string | — | 包含 alpha 通道,显示尺寸必须与第一张参考图一致 |

结果总是保存为本地文件,不以内联 Base64 返回。省略 `outputDirectory` 时,文件进入状态目录下的 `image-artifacts/`,由服务自动保留 7 天,适合预览和临时结果。正式交付到项目的素材应显式传入绝对 `outputDirectory`;自定义目录不会被后台自动清理。

### 📋 `list_image_models`

返回有效生图 profiles、Base URL、模型名、adapter、`generate/edit` 能力和分操作默认项,不返回 API key。纯环境配置也会出现在有效列表中。

### 视觉任务成功结果

```json
{
  "status": "ok",
  "model": "qwen2.5-vl",
  "profile": "office-vl",
  "summary": "图片包含一张销售数据表格。",
  "details": "表格按月份列出销售额。",
  "ocr": "January 12000 ...",
  "regions": [
    {
      "label": "销售表格",
      "confidence": 0.98,
      "bbox": { "x": 0.08, "y": 0.12, "w": 0.84, "h": 0.72 }
    }
  ]
}
```

成功任务中的视觉结果固定为 `status: "ok"`。Provider 输出无法满足 schema、配置错误、媒体错误、网络错误或超时会转为任务级 `failed`,脱敏原因位于 `error`,不会把不完整的视觉对象伪装成成功结果。

`bbox` 使用 0–1 归一化坐标,并要求 `x + w <= 1`、`y + h <= 1`。

### 生图任务成功结果

```json
{
  "status": "ok",
  "operation": "generate",
  "profile": "image2",
  "model": "gpt-image-2",
  "images": [
    {
      "path": "D:/project/generated-2026-08-09T00-00-00-000Z-uuid.png",
      "mimeType": "image/png",
      "width": 1024,
      "height": 1024,
      "bytes": 123456
    }
  ],
  "warnings": []
}
```

以上对象位于成功任务的 `result` 字段。任务失败时不返回部分图片路径,错误通过任务级 `error` 提供。

生图或编辑成功任务返回 `recommendedAction: "report_result"`。Agent 默认直接交付图片路径,不自行打开或再次分析图片;复查仅在用户明确要求执行检查、比较、质量验证或迭代验收时进行。诸如“高质量、写实、指定构图”的提示词仍只是生成约束,不构成复查授权,从而避免额外视觉调用、耗时和费用。

<a id="image-providers"></a>
## 🎨 Image2 与自定义生图模型

### 内置 OpenAI Images adapter

内置 adapter 调用:

- `POST /v1/images/generations`:JSON 请求;
- `POST /v1/images/edits`:multipart 请求;
- 单参考图字段为 `image`,多参考图重复使用 `image[]`;
- 支持已知响应字段 `b64_json`、`image_base64`、`base64`、有效 `image`、有效 `result` 和 `url`;
- 最多扫描 64 个候选,并验证真实图片内容后才接受;
- 无效候选会被跳过并产生有界 warning。

### Image2 几何规则

以下内置模型名启用 Image2 编辑归一化:

```text
image2
gpt-image-2
任何以 -image-2 结尾的模型名,例如 gpt-5.4-image-2
```

Provider 画布合同:

| 约束 | 值 |
| --- | ---: |
| 最小像素 | 655360 |
| 最大像素 | 8294400 |
| 最大边长 | 3840 |
| 最大宽高比 | 3:1 |
| 尺寸倍数 | 16 |

编辑准备行为:

- 物理应用 EXIF orientation;
- 每张参考图独立居中到合规的透明 PNG 画布;
- 小图不放大,只增加透明填充;
- 超大图按比例缩小;
- 蒙版按第一张图应用 EXIF 后的显示尺寸校验;
- 蒙版随首图 placement 缩放和嵌入,填充区域为不允许编辑的 opaque 区域;
- `size=auto` 时仍以合规工作画布请求 Provider;若返回工作画布,则裁出首图 placement 并恢复首图原始显示尺寸;
- `size=auto` 时若 Provider 返回原图尺寸或其他有效尺寸,则直接保存实际结果并通过 `warnings` 说明尺寸差异,不因尺寸不一致丢弃有效图片;
- 显式 `WIDTHxHEIGHT` 时,匹配结果原样保存;不匹配结果会等比 `cover`、居中裁剪为请求尺寸并产生 warning;
- 本地裁切或尺寸适配失败时会保留 Provider 原始有效图片并 warning;对于已经返回的图片,只有空数据、无法解码、超过安全限制或请求取消才会失败。

这些规则只应用于内置 Image2 模型。其他内置模型和外部 module adapter 保持原始输入行为。

### 自定义 Provider 钩子

当 Provider 不兼容 OpenAI Images 请求、认证或响应格式时,可以配置受信任的绝对 `.mjs` / `.js` 模块。

```js
export const apiVersion = 1;

export function createImageProviderAdapter() {
  return {
    async generate(request, context) {
      // 使用 context.profile、context.signal、context.fetch
      return {
        images: [{ bytes: new Uint8Array(/* real image bytes */), mimeType: "image/png" }],
      };
    },

    async edit(request, context) {
      // request.images 和 request.mask 已解析为字节
      return {
        images: [{ bytes: new Uint8Array(/* real image bytes */), mimeType: "image/png" }],
      };
    },
  };
}
```

合同要求:

- `apiVersion` 必须为 `1`;
- adapter 至少实现一个操作;
- profile 声明的每个 operation 都必须有对应方法;
- 返回 `{ images, warnings? }`,每张图片包含非空 `Uint8Array bytes`;
- adapter 不负责写文件,核心服务统一校验并发布产物;
- 必须响应 `context.signal`;
- 长轮询可调用 `context.reportProgress(message, progress)`;
- API key 只从 `context.profile` 读取,禁止写入 adapter 源码和日志;
- 外部模块是可执行代码,只能使用用户明确批准的可信路径;
- `doctor` 只检查 adapter 文件是否存在,不执行模块代码。

配置示例:

```json
{
  "adapter": {
    "kind": "module",
    "modulePath": "D:/trusted/image-adapter.mjs"
  }
}
```

完整合同见随包 Skill:`skills/fastcar-vision-tools/references/image-provider-adapter.md`。

<a id="runtime-boundaries"></a>
## 🌊 进度、兼容性与资源边界

### 任务进度与超时隔离

长时操作已经与提交请求断开生命周期关联:MCP 客户端在拿到 `taskId` 后断开或结束原请求,不会取消后台任务。任务自己的 Provider 超时仍由对应 profile 的 `timeoutMs` 控制。

`wait_vision_task` 是普通 MCP 工具调用,不要求客户端实现后台推送通知,因而同时适用于 stdio 和 localhost HTTP。服务端为每个等待请求注册一次性终态监听器;成功、失败、取消或 shutdown 都会立即唤醒所有监听同一任务的请求。等待请求断开只释放监听器,不会取消可能已经计费的 Provider 操作。

为避开常见客户端的工具调用超时,每次等待默认限制为 20 秒、最多 25 秒。窗口结束时返回不含长 `message` 的精简心跳,Agent 续订下一次等待;任务一旦完成则立即返回完整终态。若某个客户端的硬超时短于 20 秒,可显式传入更小的 `maxWaitMs`。客户端仍需允许 Agent 发起后续工具调用,因此不承诺依赖“后台通知自动唤醒 Agent”;原生 MCP progress/notification 也不作为结果交付通道。

`get_vision_task` 每次立即返回,供恢复和诊断使用。没有 Provider 原生进度时仍会显示当前阶段和实时 `elapsedMs`;有进度时会更新 `progress` 与最多 240 个字符的 `message`。最终以 `succeeded` 中的 `result` 为唯一权威结果。

任务元数据按任务单独原子写入,终态后保留 24 小时;持久化内容不含输入 prompt、参考图字节、API key 或 Provider 请求体。任务 TTL 只删除任务 JSON,不级联删除图片;托管图片由独立的 7 天策略管理,自定义输出目录不自动删除。

### 🧹 存储生命周期

| 数据 | 默认位置 | 自动清理 | 说明 |
| --- | --- | --- | --- |
| 任务 JSON | `vision-tasks/` | 终态后 24 小时 | 终态记录在启动、每小时及任务访问时清理;损坏 JSON 和陈旧写入临时文件在启动或每小时扫描时回收 |
| 默认生图产物 | `image-artifacts/` | 7 天 | daemon / stdio 启动时立即发起后台清理,运行期间每小时清理;写入临时文件超过 24 小时后回收 |
| 显式 `outputDirectory` | 用户指定目录 | 不自动清理 | 视为正式用户产物;只能通过明确的清理命令或用户自己的流程删除 |
| 远程视频临时文件 | 系统临时目录 | 任务结束时 | 成功、失败和取消都会清理 |
| daemon 日志 | `daemon.log` | 按容量轮转 | 单份最多 10 MiB,保留当前日志和 2 份历史日志 |

查看托管目录占用:

```bash
mcp-vision-tools artifacts status
mcp-vision-tools artifacts status --agent --json
```

清理超过 7 天的托管图片,或明确清空全部托管图片:

```bash
mcp-vision-tools artifacts cleanup
mcp-vision-tools artifacts cleanup --all
```

也可以显式指定自定义输出目录:

```bash
mcp-vision-tools artifacts status "D:\project\images"
mcp-vision-tools artifacts cleanup "D:\project\images"
mcp-vision-tools artifacts cleanup "D:\project\images" --all
```

清理只检查目标目录的第一层,不递归进入子目录,并且只识别 `generated-*`、`edited-*` 及对应原子写临时文件;其他文件、目录和符号链接始终忽略。为避免破坏正在保存的图片,不足 24 小时的写入临时文件即使使用 `--all` 也会保留。`--all` 是显式删除操作,只应在确认正式产物不再需要时使用。

### Chat Completions 兼容降级

视觉 Provider 优先使用严格 `json_schema`。端点明确拒绝能力时按需降级:

```text
json_schema → prompt 约束 JSON
SSE         → 普通响应
reasoning_effort → 省略
max_tokens  → max_completion_tokens → 省略 token 参数
```

兼容性尝试共享同一个总 deadline,不会为每次重试重新计算完整超时。

能力缓存按 profile、Base URL、model、API key 的 SHA-256 hash 和 reasoning effort 隔离,不保存明文 API key。

### 输出 token 上限

| intent | 上限 |
| --- | ---: |
| `summarize` | 512 |
| `locate` | 2048 |
| `analyze` | 4096 |
| `ocr` | 8192 |
| `video` | 8192 |

### 媒体与响应限制

| 资源 | 限制 |
| --- | ---: |
| 单张输入图片 | 64 MiB |
| 图片像素 | 100 MP |
| 自动压缩阈值 | 4 MiB |
| 输入视频 | 512 MiB |
| 视频抽帧 | 1–16 帧 |
| 编辑参考图 | 最多 16 张 |
| 编辑图片与蒙版合计 | 128 MiB |
| 生图输出数量 | 1–4 张 |
| 单张生图结果 | 64 MiB |
| 生图结果合计 | 128 MiB |
| 生图成功 JSON | 192 MiB |
| 生图非 2xx body | 2 MiB |
| 生图候选扫描 | 64 个 |
| Chat Completions 响应 | 2 MiB |
| 单个 SSE event | 256 KiB |
| FFmpeg 输出 | 1 MiB |

本地文件先通过 `stat` 预检,远程媒体按实际流式字节数限制。图片内容由 Sharp 识别,不信任扩展名或响应头。

### 图片处理原则

- 支持 JPEG、PNG、WebP、GIF;
- MIME 来自实际图片格式;
- 默认不裁剪、不放大;
- OCR 使用更高质量编码;
- `original` 保持原始字节;
- 产物先写同目录临时文件,再以无覆盖方式发布;
- 文件系统不支持 hardlink 时回退到同目录原子 rename;
- 多图保存失败时回滚本次已发布文件。

### 视频处理原则

- 本地视频不整体读入内存;
- 远程视频有界流式下载;
- FFmpeg 子进程具有总超时、输出上限和取消;
- 每个远程任务使用独立临时目录;
- 完成、失败或取消后清理临时文件。

<a id="operations"></a>
## 🩺 运维与诊断

### daemon 生命周期

- 首次启动选择可用端口,后续优先复用;
- 并发 `start` 通过 owner lock 收敛到一个实例;
- 状态保存失败时立即关闭监听,避免孤儿服务;
- `stop` 校验 health、instance ID 和 PID;默认检测到活动任务时返回 `ACTIVE_VISION_TASKS`,daemon 保持运行且继续接受任务;
- `start`、`restart` 和 `stop` 只有在用户明确授权 `--force` 后,才会把活动任务持久化为 `interrupted`、取消执行并关闭 daemon;
- 重启发现遗留的 `queued/running` 任务时标记为 `interrupted`,不自动恢复或重试;
- 启动和每小时扫描任务目录,回收损坏元数据与陈旧原子写临时文件;
- daemon 日志写入前按 10 MiB 轮转,最多保留 3 份;
- 替换启动失败时尽力恢复旧 daemon。

Agent 收到 `ACTIVE_VISION_TASKS` 后,应读取 `activeTasks[].taskId`,逐个使用 `wait_vision_task` 等待终态,再重试原生命周期命令。不得自行追加 `--force`;只有用户明确接受任务中断及潜在重复计费风险时才能强制执行。

### 状态目录

| 平台 | 默认目录 |
| --- | --- |
| Windows | `%LOCALAPPDATA%/fastcar-vision` |
| macOS | `~/Library/Application Support/fastcar-vision` |
| Linux | `$XDG_STATE_HOME/fastcar-vision` 或 `~/.local/state/fastcar-vision` |

目录文件:

```text
daemon.json
daemon-settings.json
daemon.log
daemon.log.1
daemon.log.2
provider-capabilities.json
vision-tasks/
image-artifacts/
```

### 启动校验

`start` 和 `restart` 在停止旧实例前验证默认视觉模型:

- `/v1/chat/completions` 可连接;
- 没有明显认证、限流或模型不存在错误;
- HTTP 200 body 至少具有 Chat Completions 基本结构。

校验不上传图片,因此:

```json
{
  "reachable": true,
  "endpointVerified": true,
  "visionVerified": false
}
```

表示端点可用,不证明模型一定支持图片输入。

### Doctor

```bash
mcp-vision-tools doctor
mcp-vision-tools doctor --agent --json
```

| 检查项 | 内容 |
| --- | --- |
| config | 视觉配置、profiles、默认项 |
| endpoint | 默认视觉模型端点 |
| imageGeneration | 有效生图配置、工具表面、adapter 文件 |
| daemon | PID、instance ID、health |
| MCP | server name、initialize、tools/list |
| Skill | current、missing、mismatch、disabled 或 error |
| clients | 客户端是否指向当前精确 URL |

显式禁用 Skill 是合法的附属状态,不会单独导致 Doctor 失败。

### 常见问题

#### 找不到 `mcp-vision-tools`

```bash
npm install -g @fastcar/mcp-vision-tools
npm prefix -g
```

也可以直接运行:

```bash
npx -y @fastcar/mcp-vision-tools doctor
```

#### Agent 看不到 MCP 工具

```bash
mcp-vision-tools status
mcp-vision-tools doctor
mcp-vision-tools setup
```

随后重启客户端或创建新 Agent 会话。

#### 添加了生图模型,但没有生图工具

```bash
mcp-vision-tools image-models list
mcp-vision-tools restart
```

确认 profile 的 `operations` 包含需要的 `generate` 或 `edit`。

#### 客户端仍使用旧端口

```bash
mcp-vision-tools setup
```

#### API 地址缺少 `/v1`

CLI 会自动规范化。不要填写完整 `/chat/completions` 路径。

#### API key 或模型错误

```bash
mcp-vision-tools models edit <profile>
mcp-vision-tools restart
```

生图配置使用:

```bash
mcp-vision-tools image-models edit <profile>
mcp-vision-tools restart
```

#### OCR 不清晰

使用 `intent: "ocr"`、`imageMode: "quality"` 或 `original`,并选择适合 OCR 的视觉模型。

#### 视频分析过慢

减少 `frames`,优先使用本地文件,并避免设置过高的 `VISION_VIDEO_CONCURRENCY`。

#### FFmpeg 无法启动

```text
VISION_FFMPEG_PATH=/path/to/ffmpeg
```

Windows 上的 `spawn EBUSY` 通常来自杀毒软件、索引器或其他进程短暂锁定二进制文件,可等待重试或改用独立 FFmpeg。

<a id="security"></a>
## 🔐 安全边界

### API key

- 交互式输入不回显;
- 不写入 CLI 参数和普通日志;
- Provider 错误会清理当前 API key 与 Bearer token;
- capability cache 只保存凭据 hash;
- 配置文件尽力设置为仅当前用户可读写;
- 模型列表和 MCP 列表不返回 API key。

### 本地文件权限

MCP server 可以读取启动用户有权限访问的本地路径。不要让不可信远程用户直接控制文件路径参数。

### 远程 URL 与 SSRF

媒体 HTTP(S) URL 有意保持开放,包括 localhost、私网 IP、内网域名和重定向目标。这便于分析本地开发资源,但存在明确的 SSRF 风险。

不要将本 MCP 直接暴露给可任意提交 URL 的不可信公网用户。面向此类场景时,应在外层增加网络隔离、URL allowlist、代理和访问控制。

### localhost MCP

HTTP daemon 只监听 `127.0.0.1`,校验 Host 与 Origin;`/shutdown` 需要随机内部 token。

### 子进程

后台 daemon 必须在 CLI 退出后继续运行,视频抽帧也必须调用随包的 `ffmpeg-static` 或用户明确配置的 FFmpeg 二进制,因此这两处子进程不可由纯 JavaScript 库等价替代。两处都使用 `shell: false` 和独立参数数组,不拼接或解释 shell 命令;daemon 只启动包内 bootstrap,媒体路径只作为 FFmpeg 参数传递。

### 外部 adapter

module adapter 拥有代码执行能力并可访问 profile API key。服务不会自动发现或下载 adapter,只接受显式配置的绝对 `.mjs` / `.js` 路径。

<a id="agent-skill"></a>
## 🧩 Agent Skill

任意 CLI 命令首次运行时会检查包内 `fastcar-vision-tools` Skill,并在缺失或内容不一致时同步到用户级目录:

```text
~/.agents/skills/fastcar-vision-tools
```

它是每个用户安装一份,不会为每个 Agent 重复安装。

```bash
mcp-vision-tools skill status
mcp-vision-tools skill sync
mcp-vision-tools skill uninstall
```

生命周期:

| 操作 | 行为 |
| --- | --- |
| 任意 CLI 启动 | missing / mismatch 时尝试自动修复 |
| `skill uninstall` | 删除 Skill,并创建 `.fastcar-vision-tools.disabled` 标记 |
| 后续 CLI 启动 | 发现禁用标记后保持禁用,不自动装回 |
| `skill sync` | 删除禁用标记并显式重新安装 |

本包不使用 `preinstall` 或 `postinstall` 生命周期脚本;安装 npm 包本身不会写入用户级 Skill 目录。

<a id="development"></a>
## 🛠️ 开发与发布

### 本地开发

```bash
npm install
npm run build
npm test
```

核心目录:

```text
src/
  cli.ts                    # CLI 与 Doctor
  daemon-log.ts             # 有界 daemon 日志轮转
  image-artifacts.ts        # 生图产物发布、统计与清理
  vision-task.ts            # 异步任务、事件等待与 TTL
  config-store.ts           # 视觉配置持久化
  image-config-store.ts     # 生图配置持久化
  file-lock.ts              # 跨进程锁与原子替换
  server.ts                 # MCP 工具注册
  media/                    # 图片与视频解析
  provider/                 # Provider 与 Image2 几何
  tools/                    # MCP 工具实现
skills/                     # 随包 Agent Skill
scripts/                    # smoke 与验证脚本
test/                       # Node.js 测试
```

### 验证

```bash
npm test
node scripts/smoke-mcp.mjs
node scripts/smoke-call.mjs
npm pack --dry-run
```

测试覆盖全部 MCP 工具合同、配置迁移和并发写入、媒体真实性与限制、Provider fallback、SSE、队列、任务 TTL 与异常残留、托管图片保留策略、daemon 生命周期与日志轮转、客户端注册回滚、Image2 几何、真实 stdio MCP 调用、自定义 adapter、Skill 和 CLI 自动修复。

真实视觉模型和付费图片模型调用需要有效凭据,不属于默认自动化测试。

### 发布

```bash
npm test
npm pack --dry-run
npm publish --access public
```

`prepublishOnly` 会运行 TypeScript 构建。scoped public package 发布时必须使用 `--access public`。

## 📄 License

MIT

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a clearly distinct purpose: image analysis, video analysis, and model listing. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tool names follow the consistent verb_noun pattern: analyze_image, analyze_video, list_vision_models. This provides a predictable and clear naming convention.

Tool Count5/5

With 3 tools, the server is well-scoped and focused on its core capabilities. Each tool earns its place and the count is within the ideal range.

Completeness4/5

The server covers the primary functions of image/video analysis and model discovery. Minor gaps exist such as model management or more granular analysis options, but core workflows are well supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues