第23课 · 用 MCP 让任何 AI 都能看图

本节要点
- 承接第 22 课:上一节用「observer 子代理」给 DeepSeek 加识图能力,但那依赖 oh-my-opencode-slim 插件
- 本节讲一个更通用的办法:配置一个 Vision MCP,任何支持 MCP 的 AI 工具(Claude Code、OpenCode)都能用,Windows 和 Mac 都适用
- 什么是 MCP?一句话:AI 的「万能插座」,工具做成 MCP 插头,任何 AI 即插即用
- 一段现成指令:复制粘贴给 AI,它交互式问你三个问题,自动创建识图工具并注册
- ⚠️ 无论 Claude Code 还是 OpenCode,装好 MCP 后都必须退出重启才能生效
- 配好后,AI 遇到图片会自动调用
analyze_image工具识别
1. 承接:为什么还要学第二种方式?
第 22 课我们讲了让 DeepSeek 能看图的第一种方式——给 oh-my-opencode-slim 插件配一个 observer 子代理。它能用,但有一个限制:依赖那个插件。
这一节讲第二种方式:配置一个 Vision MCP。它的好处是更通用——
| 对比 | observer 子代理(第22课) | Vision MCP(本课) |
|---|---|---|
| 依赖 | 必须装 oh-my-opencode-slim 插件 | 不依赖任何插件 |
| 适用 | OpenCode / Claude Code(装了插件的) | 任何支持 MCP 的 AI 工具 |
| 模型要求 | 视觉 且 支持 tool calling | 只要支持视觉 |
简单说,MCP 方案是「一次配置,到处通用」。
2. 先搞懂:MCP 是什么?
配置之前,先花一分钟搞懂 MCP 是什么。不懂也没关系,你可以直接跳到下一节复制指令——AI 会帮你搞定一切。但了解一下,对你以后用 AI 有帮助。
MCP = AI 的「万能插座」
想象你的电脑有各种各样的插头:USB、Type-C、老式圆孔……每个都不一样。如果你想给 AI 接一个新的外部工具(比如看图、查数据库、发邮件),以前得每个 AI 单独写一套对接代码,很麻烦。
MCP(Model Context Protocol,模型上下文协议)就是一个统一的「插座标准」。 只要工具做成 MCP 的插头,任何支持 MCP 的 AI 都能即插即用,不用重复开发。
💡 你不用学 MCP 的细节。你只需要知道:有这么个东西,AI 能帮我们写 MCP、配 MCP。我们告诉它「我要一个能识图的 MCP」,它就帮我们做好插头、插上插座。这也是用 AI 的一个重要思路——不用啥都会,知道有啥、会让 AI 帮你做就行。
不懂就问 AI
如果你看完还是不太理解,直接问 AI。在 Claude Code 里有个特别好用的命令 /btw(by the way 的缩写),可以不打断主会话地问 AI 一个问题:
在 Claude Code 里输入:
/btw 请用通俗易懂的语言给我介绍一下什么是 MCP
它会在旁边给你解释,不会打断它正在干的主活儿。问完按左上角 Esc 键就回到主会话。
AI 是你最好的老师
你不会的概念、不懂的报错、想了解的工具,都可以直接问 AI。这比百度搜出来的垃圾信息靠谱多了。
3. 准备:一个支持视觉的 API Key
和第 22 课一样,你需要一个支持看图的模型 API Key。推荐用你平时在用的平台(任意一个):
- 阿里云百炼(上一节用的,有 qwen-vl 系列视觉模型)
- 硅基流动(聚合多个开源模型,便宜)
- 其他有多模态模型的平台都行
如果你第 22 课已经申请过阿里云百炼的 API Key,直接复用那个就行,不用重新申请。还没申请的,回第22课第4节看流程。
4. 核心:复制这段指令,粘贴给 AI
这是本课的重头戏。把下面整段指令复制,粘贴给你正在用的 OpenCode 或 Claude Code 会话。
它会像安装向导一样,问你三个问题,然后自动帮你:创建识图工具 → 注册到你的 AI 工具 → 让你测试。
# 任务:配置一个 Vision MCP(让 AI 能看图)
## 背景
主模型不支持图片(如 DeepSeek)。配置一个本地 Vision MCP server,提供 `analyze_image` 工具:它把图片发给视觉模型,拿到文字描述返回给主模型。配好后这个 AI 工具就具备看图能力,任何支持 MCP 的工具都能用。
## 硬性要求(配错就跑不起来)
1. **Node.js ≥ 18**(推荐 20+),先检测,不够就停下来让我升级
2. `package.json` 必须有 `"type": "module"`——MCP SDK 只支持 ESM
3. `index.js` 里 import SDK 的路径必须带 `.js` 后缀
4. 视觉模型只需支持「图像输入」即可
5. **Claude Code 和 OpenCode 的 MCP 配置字段格式不同,不能混用**(见 Step 5)
## 执行步骤
### Step 1:向我确认三件事
- 在**哪个 AI 工具**里用?(Claude Code / OpenCode / 两个都要)
- 视觉模型用**哪家服务商**?(阿里云百炼 / 硅基流动 / OpenAI / 智谱 / 其他)
- **API Key** 是多少?
### Step 2:检测 OS + Node 版本
- 检测 OS(Mac/Linux 用 `bash`+`curl`;Windows 用 PowerShell+`Invoke-RestMethod`)
- 跑 `node -v`,低于 18 就停下来让我先升级
- 确定 MCP server 存放路径:
- Mac/Linux:`~/.vision-mcp/`
- Windows:`%USERPROFILE%\.vision-mcp\`
### Step 3:拉取服务商模型列表,选最新的视觉模型
**(a)** 用 API Key 请求 `{baseURL}/models`(带 `Authorization: Bearer {apiKey}`)。各 baseURL:
- 阿里云百炼:`https://dashscope.aliyuncs.com/compatible-mode/v1`
- 硅基流动:`https://api.siliconflow.cn/v1`
- 智谱:`https://open.bigmodel.cn/api/paas/v4`
- OpenAI:`https://api.openai.com/v1`
```bash
# Mac / Linux
curl -s "{baseURL}/models" -H "Authorization: Bearer {apiKey}"
```
```powershell
# Windows PowerShell
Invoke-RestMethod -Uri "{baseURL}/models" -Headers @{Authorization="Bearer {apiKey}"}
```
**(b)** 筛名字含 `vl`/`vision`/`vlm`/`4o`/`llava` 的模型,排除纯文本/embedding/tts。
**(c)** **查官方文档**确认候选支持「图像输入」:
- 阿里云百炼:`https://help.aliyun.com/zh/model-studio/getting-started/models`
- 硅基流动:`https://docs.siliconflow.cn/cn/userguide/capabilities/multimodal-vision`
- 智谱:`https://open.bigmodel.cn/dev/howuse/model`
**(d)** 选**版本最新、参数量较大**的(如 `qwen3-vl` > `qwen2.5-vl`;`-max`/`-plus` 优先于 `-flash`/`-lite`)。把选择和依据告诉我。⚠️ 没有视觉模型就停下来让我换服务商。
### Step 4:创建 MCP server
**(a)** 创建 Step 2 的目录,进入它。
**(b)** 写入 `package.json`:
```json
{
"name": "vision-mcp-server",
"version": "1.0.0",
"type": "module",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.29.0",
"zod": "^3.23.0"
}
}
```
**(c)** 写入 `index.js`(完整代码,直接写入,API Key/模型/地址都走环境变量):
```javascript
#!/usr/bin/env node
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import fs from 'fs';
import path from 'path';
const API_KEY = process.env.VISION_API_KEY;
const BASE_URL = process.env.VISION_BASE_URL;
const MODEL = process.env.VISION_MODEL;
if (!API_KEY || !BASE_URL || !MODEL) {
console.error('缺少环境变量 VISION_API_KEY / VISION_BASE_URL / VISION_MODEL');
process.exit(1);
}
const MIME = {
'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
'.gif': 'image/gif', '.webp': 'image/webp', '.bmp': 'image/bmp',
};
const server = new McpServer({ name: 'vision-server', version: '1.0.0' });
server.tool(
'analyze_image',
'分析图片内容并返回文字描述。支持本地文件路径或图片URL。',
{
image_url: z.string().describe('图片的本地路径或URL,如 /Users/x/photo.png 或 https://example.com/a.jpg'),
prompt: z.string().optional().describe('想问的问题,如"识别图中的文字"。不填则默认描述整张图'),
},
async ({ image_url, prompt }) => {
const question = prompt || '请详细描述这张图片的内容。';
try {
let url = image_url;
// 本地文件 → base64 data URL
if (!url.startsWith('http') && !url.startsWith('data:')) {
const fp = path.resolve(url);
if (!fs.existsSync(fp)) {
return { content: [{ type: 'text', text: `文件不存在: ${fp}` }] };
}
const mime = MIME[path.extname(fp).toLowerCase()] || 'image/png';
url = `data:${mime};base64,${fs.readFileSync(fp).toString('base64')}`;
}
// 调用视觉模型 API
const res = await fetch(`${BASE_URL}/chat/completions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}` },
body: JSON.stringify({
model: MODEL,
messages: [{
role: 'user',
content: [
{ type: 'image_url', image_url: { url } },
{ type: 'text', text: question },
],
}],
max_tokens: 2000,
}),
});
if (!res.ok) {
return { content: [{ type: 'text', text: `API错误(${res.status}): ${await res.text()}` }] };
}
const data = await res.json();
const text = data.choices?.[0]?.message?.content || '模型未返回内容';
return { content: [{ type: 'text', text }] };
} catch (e) {
return { content: [{ type: 'text', text: `出错: ${e.message}` }] };
}
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
```
**(d)** `npm install`,然后跑 `node index.js`——不报错、不退出(挂着)就说明正常,`Ctrl+C` 停掉。
### Step 5:注册到 AI 工具(字段格式不同,别抄混)
准备四个值:`INDEX_PATH`(index.js 绝对路径,Windows 在 JSON 里用 `\\` 或 `/`)、`VISION_API_KEY`、`VISION_BASE_URL`、`VISION_MODEL`。
#### 情况 A:Claude Code
用命令注册(用户级,全局可用,JSON 用单引号包裹):
```bash
claude mcp add-json --scope user vision '{"type":"stdio","command":"node","args":["INDEX_PATH"],"env":{"VISION_API_KEY":"你的key","VISION_BASE_URL":"你的baseURL","VISION_MODEL":"你的模型ID"}}'
```
报错就退回:在项目根目录创建 `.mcp.json`,内容同下表 Claude Code 列。
#### 情况 B:OpenCode
没有 CLI 命令,编辑配置文件(Mac/Linux `~/.config/opencode/opencode.json`;Windows `%USERPROFILE%\.config\opencode\opencode.json`),在 `mcp` 字段加入:
```jsonc
{
"mcp": {
"vision": {
"type": "local",
"command": ["node", "INDEX_PATH"],
"enabled": true,
"environment": {
"VISION_API_KEY": "你的key",
"VISION_BASE_URL": "你的baseURL",
"VISION_MODEL": "你的模型ID"
}
}
}
}
```
#### 字段差异对照(最易出错)
| 字段 | Claude Code | OpenCode |
|------|------------|----------|
| 类型 | `"type": "stdio"` | `"type": "local"` |
| 命令 | `"command":"node"` + `"args":["路径"]` 分开 | `"command":["node","路径"]` 合并 |
| 环境变量 | `"env"` | `"environment"` |
| 启用 | 默认启用 | 必须 `"enabled": true` |
两个工具都要的话,A 和 B 都做一遍。
### Step 6:测试
- 重启工具(配置改动要重启生效),会话里 `/mcp` 确认 vision 已连接
- 让我准备一张测试图(Mac/Linux `/tmp/test.png`;Windows `$env:TEMP\test.png`),然后对 AI 说:
```
用 analyze_image 工具分析这张图片:<图片路径>
```
- 成功标志:AI 调用了 analyze_image 工具,返回了图片描述
### Step 7:排查(失败时按顺序检查)
1. `node -v` ≥ 18?
2. `package.json` 有 `"type": "module"`?(报 `require` 错就是没有)
3. `node index.js` 能启动?(看 import 路径是否带 `.js`、依赖装好没)
4. 报「缺少环境变量」?→ env/environment 没写对
5. `/mcp` 里没有 vision?→ 字段格式错了,对照上面差异表(多半是 Claude/OpenCode 抄混了)
6. 返回「API错误 401」?→ Key 错或过期
7. 返回其他 API 错误?→ 模型 ID 拼错或不支持图像,回 Step 3
## 完成后报告给我
- OS、Node 版本、MCP server 路径
- 选了哪个视觉模型、为什么
- 注册到哪个工具、配置片段(key 打码)
- 测试是否通过、AI 有没有调用 analyze_image、描述准不准
- 给我一个以后让 AI 看图的使用示例它会怎么引导你
把指令发出去后,它会问你三个问题,你照着回答就行:
- 「在哪个 AI 工具里用?」 → OpenCode / Claude Code / 两个都要
- 「视觉模型用哪家服务商?」 → 比如「阿里云百炼」
- 「API Key 是多少?」 → 把你申请的 key 粘贴给它
然后它会自动去拉取这家服务商有哪些模型、判断哪些是多模态的、创建识图工具、注册到你的 AI 工具。
想更快?直接告诉它用哪个模型
它会联网去查哪个模型合适,这一步要花一两分钟。如果你已经知道用哪个多模态模型(比如阿里云百炼的 qwen-vl-max),回答时直接说:
「阿里云百炼,用
qwen-vl-max,API Key 是 sk-xxx」
它就跳过联网查询,直接配置,几秒钟搞定。
5. 配置过程的小技巧
配置时 AI 会跑一堆命令(装依赖、写文件、注册),这几个技巧能让你看得更清楚、更省心:
OpenCode:打开「自动接受权限」和「显示思考」
OpenCode 每执行一个命令都会问你要不要允许,点多了很烦。打开设置:
- 点 OpenCode 的设置(齿轮图标)
- 找到**「自动接受权限」**,打开——命令就不用每次确认了
- 找到**「显示推理摘要 / 显示思考」**,打开——你能看到 AI 的思考过程,知道它在干嘛,不会干等
Claude Code:用 /btw 不打断主会话问问题
Claude Code 有个特别好用的命令 /btw(by the way)。配置要等一会儿,你想问它「进度怎么样」「MCP 是什么」,又不想打断它正在干的活,就:
输入
/btw 现在进度怎么样了?
它会在旁边回答你,不影响主进程。问完按左上角 Esc 键回到主会话。
终端粘贴图片:Mac 也是 Ctrl+V
测试识图时要往终端里粘贴图片。注意一个坑:
- 不管你是 Mac 还是 Windows,在终端里粘贴都是按
Ctrl + V - Mac 用户千万别按
Cmd + V(那是系统级的粘贴,在终端里不一定管用)
这个很多人第一次会按错。
6. ⚠️ 装好后必须重启才能生效
这一步特别重要,很多人配完不重启,直接测试,发现「怎么没生效」——其实配置没问题,只是没重启。
无论你用的是 Claude Code 还是 OpenCode
MCP 配置完成后,必须把 AI 工具完全退出再重新打开,新装的 MCP 才会被加载。直接在原来的会话里测试是测不出来的。
- OpenCode:关掉窗口重新启动
- Claude Code:退出(
/exit或关掉终端)重新进入
重启后,在会话里输入 /mcp,你应该能看到列表里多了一个 vision——说明加载成功了。
7. 测试:让 DeepSeek 看图
重启确认 vision 出现在 MCP 列表后,新开一个会话测试:
- 随便截一张图(或复制一张网上的图)
- 在终端里用
Ctrl + V(Mac 也是)粘贴给 AI - 让它「识别一下图片内容」
如果配置成功,你会看到:DeepSeek(依然是那个便宜的文本模型)遇到图片后,会自动调用 analyze_image 这个 MCP 工具去识别,然后把图片内容告诉你。
💡 怎么确认它真的用了 MCP? 看它的执行过程,会出现「调用 analyze_image 工具」这样的字样。说明它不是靠主模型自己看的(它看不了),而是把图交给了你配的识图工具。
8. 如果你同时配了 observer 子代理
如果你第 22 课也配了 observer 子代理,这里有个小情况要知道:
测试识图时,AI 可能会先尝试调用 observer 子代理(因为上一节课配过)。如果你这台电脑没配好 observer,或者你想只用 MCP 这一种方式,可以把 observer 禁用掉:
- 在 oh-my-opencode-slim 配置里,把
observer加回disabled_agents - 或者直接告诉 AI:「把 observer 子代理禁用,我只想用 MCP 识图」
这样 AI 遇到图片就只会调用 MCP 的 analyze_image,不会再去试 observer。
💡 两种方式选一个就行:observer 子代理(第22课)和 Vision MCP(本课)都能让 DeepSeek 看图,没必要两个都开。建议用本课的 MCP 方式,更通用。
9. 三种方式总结
到这里,让 DeepSeek(或其他纯文本模型)能看图,我们已经讲了三种方式:
| 方式 | 做法 | 适用 | 推荐度 |
|---|---|---|---|
| ① 直接用多模态模型 | 把主模型换成支持看图的(如智谱 GLM、Kimi 等) | 任何工具 | ⭐⭐⭐ 最省事,原生支持 |
| ② observer 子代理 | 给 oh-my-opencode-slim 配一个识图子代理(第22课) | 装了该插件的 | ⭐⭐ 受插件限制 |
| ③ Vision MCP(本课) | 配一个识图 MCP 工具,任何 AI 都能用 | 任何支持 MCP 的工具 | ⭐⭐⭐ 最通用 |
💡 如果预算允许,最推荐的还是方式 ①——直接用多模态模型,它原生就能看图,最省心。方式 ② 和 ③ 是给「想继续用便宜的 DeepSeek」的人准备的补救方案。
10. 常见问题与避坑
10.1 MCP 装好了,但粘贴图片不生效?
这是群里高频问题。Vision MCP 设计的入口是图片路径或 URL,不是直接拖图片附件。
如果粘贴图片后 AI 没调用 analyze_image,最稳妥的做法是:
- 把图片保存到本地,比如
/tmp/test.png(Mac/Linux)或$env:TEMP\test.png(Windows) - 对 AI 说:「用 analyze_image 工具分析这张图片:
/tmp/test.png」
💡 多模态模型(如 Kimi、GLM)通常可以直接粘贴图片;但 DeepSeek + MCP 识图时,给路径是最稳的,避免 opencode 丢弃附件。
10.2 /mcp 里看不到 vision?
如果重启后输入 /mcp 没有 vision,按这个顺序排查:
- 真的重启了吗? 不是关标签页,是完全退出 AI 工具再重开
- 字段格式错了吗? Claude Code 用
"type":"stdio"+"args",OpenCode 用"type":"local"+"command",别混用 node index.js能单独跑起来吗? 不能的话看报错:Node 版本不够、package.json没"type":"module"、import 路径没写.js- 路径写对了吗? Windows 路径在 JSON 里用
\\或/
10.3 阿里云百炼 vs 硅基流动,哪个更好?
两家都能用,差异主要是:
| 对比 | 阿里云百炼 | 硅基流动 |
|---|---|---|
| 模型 | qwen-vl 系列,文档全 | 开源模型多,选择多 |
| 价格 | 按量,稳定 | 通常更便宜 |
| 新手友好度 | 更推荐 | 需要自己会挑模型 |
建议新手先用阿里云百炼跑通,熟悉后再尝试硅基流动省钱。
群友验证的硅基流动模型
Zidi King 大二子弟 Ai 实测:硅基流动调用 Qwen3.5-397B 视觉模型,一天约 100 张图,月消费约 14 元,效果与课程方案相当。如果你在硅基流动里挑花了眼,可以先试试这个模型。
10.4 已经配了第22课的 observer,两个会冲突吗?
不会冲突,但可能「打架」——AI 遇到图片可能先尝试调 observer。如果你只想用 MCP:
- 在 oh-my-opencode-slim 配置里把
observer加回disabled_agents - 或者直接告诉 AI:「禁用 observer 子代理,只用 MCP 识图」
两门课二选一即可,没必要两个都开。
10.5 识图「昨天能用,今天又不行」?
有群友反映:配好 vision MCP 当天测试正常,第二天又识别不了图片。这是个反复出现的坑。
根因:AI 有时会「自作聪明」——它觉得 read 工具也能读图片,就先调用了 read,而不是走你的 vision MCP,结果当然识别失败。换句话说,不是 MCP 配置坏了,而是 AI 没选择走 MCP 这条路。
根治办法:把「读图任务都用 vision MCP 完成」这条规则写进全局 agents.md(不是项目级的,是全局的,这样每个项目都生效)。这样 AI 以后碰到图片就会老老实实走 MCP,不会再跑去用 read。
💡 经验:配 MCP 这类「时好时坏」的问题,多半是 AI 没按你期望的路径走。需要每次重复提醒 AI 的规则,统一写进
agents.md,一次设定长期生效,不用每次再手动说一遍。
如果还是不行,就在对话里明确点名工具:「用 vision MCP 的 analyze_image 工具分析这张图:图片路径」,强制它走对路。
关键收获
TIP
让纯文本模型(如 DeepSeek)能看图,最通用的办法是配置一个 Vision MCP:复制本课第 4 节那段指令粘贴给 AI,它会问你三个问题(用哪个工具、哪家服务商、API Key),然后自动创建识图工具并注册。Claude Code 和 OpenCode 都能用,Windows 和 Mac 都适用。最关键的一点:配完一定要退出 AI 工具重新打开(重启),MCP 才会生效——不重启直接测试会以为没配成功。终端粘贴图片统一用 Ctrl+V(Mac 也是,别按 Cmd+V)。
更多课程:课程大纲