Skip to main content
Glama
README.md
# vision-mcp

Vision delegation MCP server — 让无法直接看图的 AI Agent 把图片理解任务委托给 OpenAI 兼容的视觉模型,支持多端点自动故障转移(failover)。

## 它解决什么问题

大多数 Agent 只有文本上下文,用户发来的图片在它眼里是 `[Image omitted: ...]` 占位符。vision-mcp 向 Agent 暴露一个 `see` 工具:

- 传入**本地文件路径**或 **http(s) URL**,可选附一个问题;
- 默认行为:详细描述图片并转写其中的文字(OCR);
- 依次尝试配置的多个视觉模型端点,某个端点失败自动切到下一个。

工具描述里内置了防滥用守卫:如果 Agent 自己能看图,就不该调用这个工具。

## 安装

需要 Python ≥ 3.10。推荐用 [uv](https://docs.astral.sh/uv/):

```bash
# 方式一:从 GitHub 直接安装为全局命令
uv tool install git+https://github.com/dreamskyali2026-boop/vision_mcp.git

# 方式二:pip
pip install git+https://github.com/dreamskyali2026-boop/vision_mcp.git
```

安装后得到 `vision-mcp` 命令(stdio 传输的 MCP server)。

也可以克隆源码运行:

```bash
git clone https://github.com/dreamskyali2026-boop/vision_mcp.git
cd vision_mcp
uv sync
uv run vision-mcp
```

## 配置

### 1. 配置文件(必需)

创建 `~/.vision-mcp/config.json`,参考 [config.example.json](config.example.json):

```json
{
  "providers": [
    {
      "name": "glm-coding",
      "base_url": "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
      "model": "glm-5.3-flash",
      "api_key": "YOUR_KEY",
      "timeout": 120
    },
    {
      "name": "glm-free",
      "base_url": "https://open.bigmodel.cn/api/paas/v4/chat/completions",
      "model": "glm-4v-flash",
      "api_key": "YOUR_KEY",
      "timeout": 60,
      "max_tokens": 1024
    }
  ]
}
```

字段说明:

| 字段 | 必填 | 默认 | 说明 |
|------|------|------|------|
| `name` | ✅ | — | 端点名称,用于日志 |
| `base_url` | ✅ | — | OpenAI 兼容的 `/chat/completions` 端点(建议 https) |
| `model` | ✅ | — | 视觉模型名 |
| `api_key` | ❌ | `""` | API 密钥 |
| `timeout` | ❌ | `120` | 单次请求超时(秒),必须 > 0 |
| `temperature` | ❌ | `0.2` | 采样温度,必须 ≥ 0 |
| `max_tokens` | ❌ | `4096` | 回复 token 上限 |
| `detail` | ❌ | `"auto"` | 图像 detail 参数 |

providers 按数组顺序做 failover:第一个失败自动尝试下一个。

### 2. 环境变量(可选覆盖)

同时设置 `VISION_BASE_URL` 和 `VISION_MODEL` 时,该端点会被**插到列表最前面**优先使用:

```bash
VISION_BASE_URL=https://example.com/v1/chat/completions
VISION_MODEL=some-vision-model
VISION_API_KEY=sk-xxx
VISION_TIMEOUT=120
```

## 注册到 MCP 客户端

### Qoder / Claude Code

```bash
claude mcp add vision -- vision-mcp
```

或写入用户级 `~/.claude/settings.json`(Qoder 为 `~/.qoder-cn/settings.json`):

```json
{
  "mcpServers": {
    "vision": {
      "command": "vision-mcp"
    }
  }
}
```

### Cursor / 通用 mcpServers 配置

```json
{
  "mcpServers": {
    "vision": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/dreamskyali2026-boop/vision_mcp.git", "vision-mcp"]
    }
  }
}
```

## 使用

注册后 Agent 会获得一个 `see` 工具:

| 参数 | 类型 | 说明 |
|------|------|------|
| `image` | string | 本地文件路径或 http(s) URL |
| `question` | string? | 可选问题;缺省为"详细描述图片并转写文字" |

示例(Agent 视角):

```
see(image="/tmp/screenshot.png", question="这个报错信息是什么意思?")
see(image="https://example.com/chart.png")
```

所有 Agent 返回内容都带 untrusted 前缀标记,提示调用方将视觉模型输出当作数据而非指令(防提示注入)。

## 安全特性

- 本地文件做**魔数嗅探**(不信任扩展名):仅接受 png / jpeg / gif / webp / bmp,防止把任意本地文件(如密钥)外传给视觉端点;
- 单图上限 20 MB;
- 图片 URL 不允许携带 `user:pass@host` 凭据;
- 非 https 的 `base_url` 会输出明文告警;
- 配置校验:timeout / temperature / max_tokens 越界直接报配置错误。

## 开发

```bash
git clone https://github.com/dreamskyali2026-boop/vision_mcp.git
cd vision_mcp
uv sync
uv run pytest          # 运行测试
```

项目结构:

```
src/vision_mcp/
├── server.py     # MCP server 入口,暴露 see 工具(stdio)
├── providers.py  # 读取 ~/.vision-mcp/config.json + 环境变量
└── vision.py     # 图片处理(嗅探/base64)、多端点 failover 调用
```

## License

MIT