vision-mcp
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
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues