外观
第 7 章 · 工具、MCP 与联网
Prompt 决定 AI「想做什么」,工具决定 AI「实际能做什么」。没有工具,模型只能输出文字;有了工具,它才能读文件、改代码、跑命令、查资料。本章讲透工具系统:内置工具有哪些、如何安全地放权、怎样用 MCP 扩展能力、以及何时让 AI 联网。
本章包含 5 个知识点:
- 工具系统全景:AI 的「手眼」有哪些
- Shell 工具:让 AI 操作系统命令
- 权限系统:allow / deny / ask 的安全闸门
- MCP 服务器:给 Agent 装上外接机械臂
- 联网检索:webfetch 与 websearch 的正确用法
知识点 1:工具系统全景:AI 的「手眼」有哪些
① 定位
前面章节你已经在「用」工具了(@文件、! 命令),但可能没系统看过 AI 手里到底有什么。本知识点建立工具全景图——理解了有哪些工具,你才知道一个任务 AI 理论上能不能完成、该在哪一层放权或限制。
② 是什么(What)
V2 内置工具按用途可分四大类:
| 类别 | 工具 | 作用 |
|---|---|---|
| 文件类 | read | 读文件 / 列目录(单页上限 2000 行、50 KiB;图片与 PDF 可直接传给模型,源数据上限 20 MiB) |
glob | 按模式找文件路径(如 **/*.ts),默认上限 100 个 | |
grep | 按正则 / 字面量搜文件内容,返回路径、行号、预览 | |
edit | 在已有文件中精确替换文本(oldString 必须唯一匹配,或 replaceAll) | |
write | 新建或整体覆盖文件(自动建父目录) | |
patch | 一个补丁同时增 / 改 / 移 / 删多个文件(仅支持的 GPT 模型可用,其它模型自动降级为 edit/write) | |
| 命令类 | shell | 在宿主机 shell 中执行命令(默认前台超时 2 分钟,支持后台运行) |
| 网络类 | webfetch | 抓取单个 HTTP/HTTPS URL,默认转 Markdown(不下载图片等二进制) |
websearch | 调用搜索供应商查最新信息(第 5 个知识点详解) | |
| 协作 / 自动化类 | question | 暂停执行,向你提问并给出选项 |
skill | 按 ID 加载一个 Skill 的说明与资源(第 5 章讲过) | |
subagent | 启动子代理会话(fresh context,默认嵌套深度 1) | |
execute | 在 Code Mode 沙箱里跑 JavaScript 来组合调用工具(无文件系统、无 fetch,只能调目录内工具) |
③ 怎么做(How)
工具使用的核心原则:你只管描述想要的结果,OpenCode 自己选择工具。
text
❌ 微观管理:请先调用 grep,然后 read,再 edit……
✅ 描述结果:找到请求超时配置在哪,把默认值改成 30 秒,然后跑相关测试。后者 AI 通常会自动串联 grep → read → edit → shell。需要指定方法时也可以点名工具(「用 grep 找出 DEFAULT_TIMEOUT 的所有引用,再读这些文件」)。
日常配合动作:
- 任务描述中说清结果与约束(改什么、不能动什么、要不要跑测试);
- AI 调用工具时留意它的动作,高危操作(shell、越界路径)会触发授权询问;
- 发现它选错工具,及时打断(
Esc)或 steer 纠偏。
④ 为什么这么做(Why)
- 工具是模型与真实世界之间的唯一通道。 模型本身只能生成文本;调用
edit才能改文件、调用shell才能跑测试。Agent 的「行动力」= 模型推理 × 可用工具,缺任一项都完不成实际工作。 - 工具按最小职责切分,利于精确授权。
read与edit分离、webfetch与websearch分离,使你可以「允许读、禁止改」「允许抓指定站、禁止搜索」——细粒度工具是细粒度安全的前提。 - 让模型自选工具是因为它掌握全局计划。 你若逐步指定,一旦中间结果不符预期就要人工重新规划;模型能根据上一步结果动态决定下一步,这正是 Agent 与「脚本」的区别。
patch/execute等工具有条件地开放,体现「能力与模型 / 环境匹配」的设计:不支持的模型自动降级,保证总能完成任务。- 每个工具调用都有资源(resource)记录,权限系统据此裁决,也让你事后能审计 AI 到底做了什么。
⑤ 这样做的好处
- 任务可端到端完成:从搜索定位到修改验证,无需你手工中转。
- 你能精确控制能力边界:读 / 写 / 执行 / 联网分别放权。
- 协作省力:描述结果即可,不必规划每一步。
- 过程透明可审计:每个工具调用都显示在会话里。
- 能力可扩展:内置不够时还有 MCP(知识点 4)。
⑥ 不这么做的问题 / 坏处
- 不知道有哪些工具 → 提出 AI 根本无法完成的要求(如「直接帮我部署到服务器」却没配相应工具)。
- 微观管理每一步 → 一旦结果偏离就卡住,Agent 退化成按键精灵。
- 工具全开不加区分 → 误操作、误删、泄密的风险全部敞口。
- 不看工具调用过程 → AI 默默改错文件、跑了危险命令你都不知道。
⑦ 举一反三:三个例子
例 1(基础):识别一个任务会用到哪些工具
📌 场景:「把所有调用旧 API 函数的地方改成新函数名。」
✅ 预期工具链:grep 找引用 → read 逐个确认 → edit(或 patch)替换 → shell 跑测试验证。
🔍 讲解:这是最典型的「搜索—阅读—修改—验证」四段式。看懂工具链,你发任务时就知道该给哪些权限、预期几个动作。
例 2(进阶):点名工具改变做事方式
📌 场景:你怀疑项目里有多处同样的写法,不想让 AI 一个个文件翻。
✅ 提示:「用 grep 正则 console\\.log\\( 搜 src/ 下所有 *.ts,汇总文件与行号后先给我清单,别急着改。」
🔍 讲解:点名 grep + 约束「先给清单」,既利用了工具的高效,又把修改的决定权留在自己手里。工具选择与是否动手可以分开控制。
例 3(挑战):判断任务「工具不可达」
📌 场景:「帮我把这个功能直接发布到生产环境。」
✅ 正确判断:先问——当前环境有发布工具吗?有相应 MCP / CLI 凭证吗?若没有,AI 无法凭空完成;应先接入工具(部署平台 MCP 或 shell 权限 + 登录态),或改为让它生成发布脚本、由你执行。
🔍 讲解:成熟的使用者会先检查「能力是否可达」,而不是要求 AI 做无米之炊。Agent 的边界由工具决定,扩展边界靠 MCP 与权限,而非更恳切的 Prompt。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:不看上面的表格,按「文件 / 命令 / 网络 / 协作自动化」四类,各举出至少两个内置工具。
💡 思路提示:读搜改写、shell、fetch/search、question/skill/subagent/execute。
✅ 参考答案:
text
文件:read、glob、grep、edit、write、patch;
命令:shell;
网络:webfetch、websearch;
协作 / 自动化:question、skill、subagent、execute。🔍 讲解:能默画出这张全景图,你对「AI 能做什么」就有了完整 inventory。
练习 2(迁移型)
📝 题目:迁移到装修施工:设计师(模型)与各类工种(工具)的关系中,为什么「业主说清想要的效果、让施工方安排工种」比「业主逐个指挥工人」更高效?什么情况下业主必须介入?
💡 思路提示:全局计划、动态调整、关键节点验收。
✅ 参考答案(示例):
text
- 设计师 / 施工方掌握工序衔接,能按现场情况动态安排工种,
业主逐个指挥反而因信息不全而低效;
- 业主必须介入的情况:拆承重墙等高风险动作、预算外增项、
隐蔽工程验收。
共性:对 Agent 也应「描述结果 + 在高危 / 关键节点审批」,
把日常执行权交给模型、把安全闸门握在自己手里。🔍 讲解:工具编排与现实项目管理同理。理解「放权执行 + 关键控制」的分工,你就掌握了使用 Agent 的正确姿态。
知识点 2:Shell 工具:让 AI 操作系统命令
① 定位
Shell 是所有工具中权力最大、风险也最高的一个:它让 AI 在你的宿主机上以「你的用户身份」执行任意命令——能跑测试、装依赖、启服务,也能删文件、推代码、发请求。本知识点讲透如何安全高效地使用它。
② 是什么(What)
Shell 工具的关键事实:
| 特性 | 说明 |
|---|---|
| 执行身份 | 宿主机当前用户,拥有该用户的文件、进程、网络权限 |
| 前台超时 | 默认 2 分钟;可设置 timeout(毫秒) |
| 后台模式 | background: true 适合 dev server / 长任务,立即返回、完成时通知,默认无超时 |
| 工作目录 | 用 workdir 指定,而不是把 cd 写进命令 |
| 大输出处理 | 自动截断展示,完整输出保存在受管文件中 |
| 授权粒度 | shell action,资源是扫描器解析出的每条命令;复合命令可能被拆成多条分别授权 |
你已经在第 2 章见过 TUI 的 Shell 模式(输入框以 ! 开头,那是你手动跑命令);这里的 shell 是 AI 自动调用的工具,二者共享同一台机器但触发方式不同。
③ 怎么做(How)
- 提示中给出命令运行的约束:在哪个目录、超时多久、要不要后台,让 AI 正确传参;
- 跑测试 / 构建等常规命令时,配置 allow 规则减少打扰(知识点 3);
- dev server、watch 类长任务用后台模式,避免阻塞会话;
- 看到授权弹窗时,读一遍完整命令再批准——特别留意
rm、重定向、管道、curl | sh、git push; - 命令失败时,优先让 AI 自己读报错、迭代修复,而不是你手工转述。
④ 为什么这么做(Why)
- 编译、测试、构建只能通过 shell 完成。 读写文件解决不了「验证代码是否正确」;shell 让 Agent 形成「修改 → 运行 → 看结果 → 再修」的闭环,这是自主开发能力的关键一环。
- shell 继承的是你的全部用户权限,所以必须谨慎。 它没有沙箱:一条
rm -rf在错误目录就可能删掉个人文件,一次git push可能把未审查代码推到远端。权力真实,风险也真实。 - 扫描器把复合命令拆开授权,是为了让你看清楚。
a && b、管道、重定向可能让危险动作藏在长命令里;拆分后每条单独匹配规则,防止「批准了看起无害的命令,顺带执行了危险操作」。 - 超时 / 后台的区分匹配命令的性质。 测试命令要等结果、有超时保护;服务器进程常驻、需要通知机制——参数设计让两类任务都不卡死会话。
- 让 AI 自己迭代报错,信息损耗最小。 你手工复制粘贴报错可能漏掉关键栈帧;shell 输出直接回到模型上下文,它能拿到完整证据。
⑤ 这样做的好处
- 修改可立即验证,Agent 形成开发闭环。
- 长任务不阻塞:后台 dev server / 构建并行运行。
- 授权精确到命令,复合动作躲不过检查。
- 报错即上下文,修复迭代快。
- 常规命令配 allow 后体验顺滑,危险命令仍被拦住。
⑥ 不这么做的问题 / 坏处
- 完全禁止 shell → AI 改完代码无法验证,质量靠猜。
- shell 全部 allow → 一次误判模型意图就可能执行破坏性命令。
- 批准前不读命令 → 把对机器的控制权拱手让出。
- 用
cd串命令而不用 workdir → 路径解析脆弱,后续命令可能在错误目录执行。
⑦ 举一反三:三个例子
例 1(基础):跑测试验证一次修改
📌 场景:AI 改完一个工具函数,你希望确认没改坏。
✅ 提示:「从 packages/core 目录跑与这个模块相关的测试,超时设 5 分钟,失败就读报错继续修。」
🔍 讲解:明确 workdir、超时、失败后的处理方式,AI 就能自主闭环。把「验证」变成任务的一部分,而不是你记得才做。
例 2(进阶):后台启动 dev server
📌 场景:调试时需要一个常驻的开发服务器。
✅ 提示:「用后台模式启动 bun dev,确认它正常监听后继续做别的;它输出的 URL 和报错及时告诉我。」
🔍 讲解:后台模式立即返回、不阻塞会话,完成 / 异常时再通知——常驻进程就该这么跑,而不是占着前台等两分钟超时。
例 3(挑战):审查一条可疑命令
📌 场景:授权弹窗里出现:
bash
curl -fsSL https://example.com/install.sh | sh && rm -rf /tmp/build-cache✅ 处置:先拒绝。该命令把远端脚本直接交给 sh 执行(脚本内容你没看过),还顺带做了删除操作。若确有需要,让 AI 先 webfetch 脚本内容给你审查,或拆成「下载 → 检查 → 执行」三步分别授权。
🔍 讲解:curl | sh 等于让任意远端内容以你的身份运行,是经典高危模式。审查命令时盯住数据从哪来、动作是什么、有没有顺带操作,就能识别绝大多数风险。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:为什么说 shell 是权力最大的工具?说出 shell 工具默认前台超时时间,以及长任务应使用什么模式。
💡 思路提示:用户身份无沙箱;2 分钟;background。
✅ 参考答案:
text
shell 以宿主机当前用户身份运行,拥有该用户的文件、进程、
网络权限且无沙箱,因此权力最大、风险最高。
默认前台超时 2 分钟;dev server 等长任务应使用
background 后台模式(立即返回、完成时通知、默认无超时)。🔍 讲解:理解 shell 的能力边界与运行参数,是安全使用它的前提。
练习 2(迁移型)
📝 题目:迁移到财务授权:公司里「小额自动放行、大额需审批、转账指令要逐字核对收款人」的制度,与 shell 权限管理有何共性?
💡 思路提示:按风险分级、核对关键信息、最小授权。
✅ 参考答案(示例):
text
- 小额(常规 git 检查、测试)风险低,自动放行提升效率;
- 大额(删除、推送、执行远端脚本)需逐字核对并审批;
- 收款人 / 命令内容是关键信息,必须逐字核对防止夹带。
## 知识点 3:权限系统:allow / deny / ask 的安全闸门
### ① 定位
前两个知识点反复出现「触发授权」「配规则」,本知识点把权限系统一次讲透:规则怎么写、匹配顺序是什么、多资源操作如何裁决。掌握它,你才能把「每次弹窗」变成「常用自动、危险拦截」的稳定策略。
### ② 是什么(What)
权限规则写在 `opencode.jsonc` 的 `permissions` 数组中,每条规则三个字段:
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"permissions": [
{ "action": "shell", "resource": "*", "effect": "ask" },
{ "action": "shell", "resource": "git status *", "effect": "allow" },
{ "action": "shell", "resource": "git diff *", "effect": "allow" },
{ "action": "shell", "resource": "git push *", "effect": "deny" }
]
}| 字段 | 含义 |
|---|---|
action | 工具动作:read / edit / glob / grep / shell / webfetch / websearch / subagent / skill / question / external_directory / execute;MCP 工具形如 <server>_<tool> |
resource | 动作作用的值:路径、命令、URL、查询词、skill / agent ID |
effect | allow(直接放行)/ deny(阻止)/ ask(弹窗问你) |
三条核心规则:
- 没有任何规则匹配时,默认
ask(安全兜底); - 最后一条匹配的规则生效——所以具体例外要写在宽泛规则之后(上例先对所有 shell
ask,再给 git status/diff 开口、对 push 明令禁止); - 多资源操作(如 patch 改多个文件):任一资源
deny则整体拒绝;否则任一ask则询问;全部 allow 才放行。
匹配语法:* 匹配任意多个字符、? 匹配单个字符;路径模式匹配整个规范化路径;git status * 这样的命令模式也匹配不带参数的 git status 本身。
③ 怎么做(How)
- 先用宽规则定基调(如 shell 一律
ask、read 一律allow); - 再按高频白名单追加具体 allow(git status/diff、测试命令);
- 对绝不允许的动作追加 deny(git push、读
*.env); - 工作区外的路径需要额外配
external_directory规则(先过目录边界,再过 read/edit); - 规则改完在真实任务中观察弹窗频率,逐步把「总要点头」的安全动作加入白名单——渐进放权,而非一次全开。
④ 为什么这么做(Why)
- 默认 ask 是「失败安全」设计。 规则没覆盖到的未知动作一律先问人,保证不会因为你漏写规则而意外放行危险操作。安全系统的默认值永远应该指向更保守的一侧。
- 「最后匹配生效」让宽基调与具体例外共存。 你可以先写一条「shell 全问」,再在后面精确开洞;规则按顺序组合,不必维护一棵复杂的决策树。写规则像写防火墙:先兜底、再放行例外。
- 多资源操作「deny 优先」防止夹带。 patch 一次改 5 个文件,只要其中 1 个不该碰,整体就该阻止——否则攻击者 / 失误模型可以把敏感文件混在正常文件里绕过检查。
- 规则按配置层级合并(低优先级配置先加载、全局规则其次、Agent 规则最后),让项目、个人、单个 Agent 三层策略可以叠加;Agent 自带的权限规则附在最后,符合「最小角色」的约束。
- 通配符匹配整个规范化值,既足够表达白名单,又避免部分匹配带来的绕过(如
edit允许docs/*不会意外放行docs/../secret,因为匹配的是规范化后的完整路径)。
⑤ 这样做的好处
- 日常顺滑:高频安全动作自动放行,少被弹窗打断。
- 危险必拦:deny 是硬约束,不依赖模型自觉。
- 未知动作不失守:默认 ask 兜底。
- 策略可分层共享:项目规则进版本控制,团队统一安全基线。
- 规则可解释、可审计:每步放行 / 拦截都能追溯到具体规则。
⑥ 不这么做的问题 / 坏处
- 规则顺序写反 → 宽泛规则写在最后会吞掉前面的例外,白名单形同虚设。
- 图省事全部 allow → 安全闸门彻底消失,与没有权限系统无异。
- 全部 ask、不建白名单 → 弹窗疲劳,最后见框就回车,反而更危险。
- 忽视 external_directory → 访问工作区外资料时反复被拦或被迫整体放权。
⑦ 举一反三:三个例子
例 1(基础):给 Git 检查开白名单
📌 场景:你总被 git status、git diff 的弹窗打断,它们显然安全。
✅ 规则:先保留 { action: "shell", resource: "*", effect: "ask" },在其后追加 git status *、git diff * 的 allow;再追加 git push * 的 deny 双保险。
🔍 讲解:宽基调不动、例外随后——检查与推送区分对待,体验和安全都保住了。
例 2(进阶):保护环境文件
📌 场景:项目里有 .env / secrets/,绝不希望 AI 读取或修改。
✅ 规则:
jsonc
{ "action": "read", "resource": "*.env", "effect": "deny" },
{ "action": "read", "resource": "secrets/*", "effect": "deny" },
{ "action": "edit", "resource": "secrets/*", "effect": "deny" }🔍 讲解:即使前面有 read * allow,具体 deny 写在后面即生效。敏感资源要 read/edit 双封,防止「不让读却能改」之类的疏漏。
例 3(挑战):允许引用工作区外的只读资料
📌 场景:你让 AI 参考 ~/projects/reference/ 下的另一个仓库。
✅ 规则顺序:
jsonc
{ "action": "external_directory", "resource": "~/projects/reference/*", "effect": "allow" },
{ "action": "read", "resource": "~/projects/reference/*", "effect": "allow" },
{ "action": "edit", "resource": "~/projects/reference/*", "effect": "deny" }🔍 讲解:越界路径先过 external_directory 这道边界检查,再过 read/edit。这样 AI 能参考外部代码却不能改它——目录边界 + 只读放权是引用外部资料的标准组合。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:一条权限规则有哪三个字段?没有规则匹配时的默认效果是什么?「最后匹配生效」意味着规则应按什么顺序排列?
💡 思路提示:action/resource/effect;ask;宽泛在前、具体例外在后。
✅ 参考答案:
text
三字段:action(动作)、resource(资源)、effect(allow/deny/ask)。
无匹配时默认 ask(先问人)。
顺序:宽泛的基调规则在前,具体的例外(allow / deny)
写在其后——因为最后一条匹配规则生效。🔍 讲解:这三点是权限系统的全部骨架,写任何规则前先在脑中过一遍。
练习 2(迁移型)
📝 题目:迁移到小区门禁:「大门默认刷脸(陌生人登记)、物业人员可进设备间、快递员未经业主确认不得入楼」——这套门禁与权限系统的 allow/deny/ask 如何对应?默认策略为什么重要?
💡 思路提示:身份=resource,默认保守。
✅ 参考答案(示例):
text
- 业主刷脸自动通过 ≈ allow(高频、可信);
- 物业可进设备间 ≈ 针对特定身份 / 资源的 allow;
- 快递员需业主确认 ≈ ask;
- 明确的黑名单人员 ≈ deny;
- 陌生人默认登记 ≈ 无规则匹配时默认 ask。
默认策略重要:若默认放行,所有漏网情况全部失守;
默认保守,才能靠「逐步开白名单」获得安全。
权限系统默认 ask 与小区门禁默认登记是同一种安全哲学。知识点 4:MCP 服务器:给 Agent 装上外接机械臂
① 定位
内置工具再全也覆盖不完「操作数据库、查公司知识库、调用 Jira、读 Figma」这些具体需求。MCP(Model Context Protocol)就是标准化的外接工具协议——本知识点讲它是什么、本地与远程两类服务器如何接入,以及接入时的成本与纪律。
② 是什么(What)
MCP 是一套让 AI 客户端与外部工具服务通信的开放协议。 一个 MCP 服务器可以向 OpenCode 暴露四类能力:工具(tools)、提示(prompts)、资源(resources)、说明(instructions)。接入后,AI 就能像调用内置工具一样调用它们(权限 action 形如 <server>_<tool>)。
服务器分两类:
| 本地服务器(local) | 远程服务器(remote) | |
|---|---|---|
| 传输 | stdio,OpenCode 自己拉起一个进程 | Streamable HTTP,一个绝对 URL |
| 典型形式 | npx -y some-mcp-server | https://mcp.example.com/mcp |
| 认证 | 一般无需,或用环境变量 | 默认 OAuth(PKCE,可自动刷新),也可 oauth: false + headers 传 API Key |
| 适用 | 本机文件、本地服务类工具 | SaaS 平台托管的能力(如文档检索服务) |
最简单的接入方式是 CLI:
bash
# 远程服务器(写入当前项目配置)
opencode mcp add context7 --url https://mcp.context7.com/mcp
opencode mcp list # 查看连接状态
# 全局生效(每个项目都能用)
opencode mcp add context7 --global --url https://mcp.context7.com/mcp
# 本地服务器:命令直接跟在后面
opencode mcp add everything npx @modelcontextprotocol/server-everything远程服务器若显示 needs authentication,在 TUI 里运行 /mcps,选中该服务器完成登录。
③ 怎么做(How)
- 优先用
opencode mcp add,让 CLI 把配置写对;远程默认 OAuth,本地给启动命令; - 只想某个项目用 → 不加
--global(写进项目配置可随仓库共享);个人通用 → 加--global; - 需要环境变量、工作目录、自定义 headers 时手写
opencode.jsonc的mcp.servers,密钥用{env:NAME}占位(JSON 字符串里$NAME不会被展开); - 暂时不用的服务器用
"disabled": true(没有enabled字段); - 接入后跑一个小任务验证工具真的可调,再观察它占用的上下文量,用不上就移除。
④ 为什么这么做(Why)
- MCP 用一个标准协议替代了「每个工具写一次专用集成」。 服务器方实现一次协议,任何支持 MCP 的客户端(OpenCode 及其它)都能用——网络效应让可接入的工具生态快速扩大,你是直接受益者。
- stdio 与 HTTP 分流,匹配工具的部署形态。 本地命令零网络成本、天然继承本机环境;远程 SaaS 用 URL + OAuth,免运维。协议把差异藏在传输层,用法保持一致。
- OAuth 默认开启、凭证留在项目配置之外。 PKCE、token 刷新、动态客户端注册都是自动化的;用 API Key 时则要求走 headers +
{env:},延续第 6 章「密钥不入库」的原则。 - MCP 工具会消耗模型上下文,所以官方强调只加需要的服务器。 每个服务器的工具定义都可能被送进上下文;装得越多,窗口被挤占、模型选择工具时也更容易分心。扩展能力与保持精简是需要平衡的。
- 高优先级配置对同名服务器整体替换、而非字段合并。 这是一种可预测的覆盖语义:项目要改写全局服务器时必须给全字段,避免「以为覆盖了 key,实际继承了旧值」的意外。
codemode默认 true:MCP 工具默认经 Code Mode 暴露,多一层组合与审计的沙箱;需要直接暴露时可显式关闭——默认值仍指向更受控的一侧。
⑤ 这样做的好处
- 能力几乎无限扩展:数据库、设计、项目管理、知识库按需接入。
- 接入成本低:一条
mcp add+ OAuth 登录即可。 - 项目 / 全局分层:团队共享项目集成,个人工具不互相干扰。
- 凭证安全机制完整:OAuth 或环境变量注入,密钥不写进文件。
- 权限统一管理:MCP 工具走同一套 allow/deny/ask 规则。
⑥ 不这么做的问题 / 坏处
- 见一个装一个 → 上下文被工具定义挤占、模型选错工具,且故障面扩大。
- 把 API Key 明文写进配置 → 随项目仓库泄露,重蹈凭证管理覆辙。
- 本地服务器不锁版本 →
npx -y每次拉最新,上游发新版可能行为突变。 - 忽略
disabled字段、直接删配置 → 临时排障后无法快速恢复。
⑦ 举一反三:三个例子
例 1(基础):接入文档检索服务
📌 场景:你希望 AI 能查最新的第三方库文档,而不是凭训练记忆。
✅ 做法:
bash
opencode mcp add context7 --url https://mcp.context7.com/mcp
opencode mcp list # 看到 connected;若 needs authentication,
# 在 TUI 用 /mcps 登录然后直接问:「查一下某库当前版本 X API 的用法,给我一个可运行的最小示例。」
🔍 讲解:远程服务器 + OAuth 是最省心的组合:一条命令、一次登录,之后联网取文档就成了 AI 的标准动作。
例 2(进阶):本地数据库 MCP 走环境变量
📌 场景:本地 MCP 需要数据库密码,你不想写进配置文件。
✅ 配置:
jsonc
{
"mcp": {
"servers": {
"db": {
"type": "local",
"command": ["npx", "-y", "db-mcp-server"],
"environment": {
"DB_PASSWORD": "{env:DB_PASSWORD}"
}
}
}
}
}启动 OpenCode 前在 shell 里 export DB_PASSWORD=...(或放进不入库的环境文件)。
🔍 讲解:{env:NAME} 是配置中唯一的环境替换方式——密钥留在环境里,配置文件可以安全地进 Git。与第 6 章供应商凭证的处理完全一致。
例 3(挑战):给团队仓库配置受权限约束的 Jira MCP
📌 场景:团队希望 AI 能读 Jira issue,但不允许它直接改状态 / 评论。
✅ 做法:把远程服务器(API Key 走 headers + 环境变量、oauth: false)写进项目 opencode.jsonc;再配权限:
jsonc
{ "action": "jira_search", "resource": "*", "effect": "allow" },
{ "action": "jira_getIssue", "resource": "*", "effect": "allow" },
{ "action": "jira_update*", "resource": "*", "effect": "deny" }(具体工具名以该 MCP 暴露的名称为准;* 按 action 整体通配。)
🔍 讲解:第三方 MCP 的写操作必须像 shell 一样警惕。先列它暴露的工具,再按「读放行、写禁止」配规则,让团队安全共享集成。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:MCP 本地服务器与远程服务器在传输方式和认证上有何不同?暂时停用一个服务器应使用什么字段?
💡 思路提示:stdio 命令 vs HTTP URL + OAuth;disabled。
✅ 参考答案:
text
本地(type: local):OpenCode 通过 stdio 启动一个命令进程,
一般无需认证,密钥可经 environment 的 {env:NAME} 传入。
远程(type: remote):Streamable HTTP + 绝对 URL,默认走
OAuth(也可 oauth: false 并用 headers 传 API Key)。
暂时停用:设 "disabled": true(没有 enabled 字段)。🔍 讲解:区分两类传输与凭证方式,是正确配置 MCP 的基本功。
练习 2(迁移型)
📝 题目:迁移到手机 App 的系统授权:为什么 iOS / Android 把「相机、麦克风、通讯录」做成统一的授权弹窗、按需申请,而不是安装时一次性全给?这与 MCP「只装需要的服务器 + 按工具授权」有何共性?
💡 思路提示:最小权限、用户知情、攻击面。
✅ 参考答案(示例):
text
- 按需申请:App 用到相机时才弹窗,用户明确知情;
- 统一协议:所有 App 走同一套授权机制,用户形成稳定心智;
- 最小权限:不给与功能无关的权限,缩小数据泄露面。
共性:MCP 也应「只接入任务需要的服务器、按 server_tool
逐个授权、默认受控(codemode)」——两者都是最小权限原则:
能力按需开放,而非一次性全给。知识点 5:联网检索:webfetch 与 websearch 的正确用法
① 定位
模型的知识停留在训练截止日,且无法看到「今天发布的版本、你给的内网文档、某篇博客」。联网能力补上这块短板。本知识点讲两个网络工具的分工、搜索供应商如何配置,以及一个关键纪律:不是所有任务都该联网。
② 是什么(What)
两个工具职责分明:
webfetch | websearch | |
|---|---|---|
| 输入 | 一个具体的 HTTP/HTTPS URL | 一个搜索查询词 |
| 输出 | 该页面内容(默认 Markdown;支持 HTML/文本/JSON/XML,不抓图片等二进制) | 搜索结果,AI 再阅读并可附来源链接 |
| 超时 | 最长 120 秒 | 取决于搜索供应商 |
| 权限 | action webfetch,资源是 URL | action websearch,资源是查询词 |
| 解决的问题 | 「读这篇我给的链接」 | 「查一下最新的 / 我不知道在哪的信息」 |
websearch 需要配置搜索供应商,V2 内置四家:
| 供应商 | 环境变量 |
|---|---|
Exa(exa) | EXA_API_KEY |
Firecrawl(firecrawl) | FIRECRAWL_API_KEY |
Parallel(parallel) | PARALLEL_API_KEY |
Tavily(tavily) | TAVILY_API_KEY |
凭证通过 TUI 的 /connect 绑定,或启动前设置对应环境变量。
③ 怎么做(How)
- 有明确链接 → 直接给 URL:「读一下
<url>,总结三个要点」,让 AI 走 webfetch,不必搜索; - 要最新信息 / 不知道链接 → 用自然语言要求搜索:「查一下 Bun 最新版本的发布说明,总结变化并给来源」;首次会弹窗让你选择搜索供应商,之后记住选择;
- 想跳过选择弹窗:在
opencode.jsonc配置"websearch": { "provider": "tavily" }(或"random"自动选择可用供应商); - 完全不需要联网的环境:设
"websearch": false可把搜索工具从模型可用列表中移除; - 对内容质量要求高时,要求 AI 附来源链接,你点开原文核对——搜索结果是二手信息,关键结论要回到一手页面。
④ 为什么这么做(Why)
- 训练知识有时效边界,联网让信息锚定当下。 「最新版本号、今天的公告、近期价格」这类问题,再强的模型不联网也只能给过时答案。搜索是对知识截止日的系统性补偿。
- fetch 与 search 分工避免绕路。 你已经有 URL 时,搜索一遍再找链接纯属多余、还可能搜到错的页面;反过来没有 URL 时,fetch 无从发起。两个工具对应「已知来源」与「未知来源」两种信息状态。
- 多供应商 + random + 429 冷却,提升可用性。 某家返回 429 时自动切到其它供应商(冷却 60 秒或遵循 Retry-After),避免单点限流让整个检索能力瘫痪。这是一种轻量的冗余设计。
- webfetch 默认转 Markdown 且拒收二进制,让模型拿到的是干净文本,也防止把大文件灌进上下文;120 秒上限覆盖绝大多数页面。
- 「不该联网时不联网」是纪律而非保守。 本地代码问题联网搜索可能引入无关的过时答案(同名不同版本的库);且每次检索都会带来来源可信度问题。本地证据充分时,答案应从证据里推出,而不是上网碰运气。
- 提供来源链接是可验证性的要求。 联网回答若不给出处,你无法区分「事实」与「模型借搜索之名的编造」;有链接才能追溯核对,这与第 1 章讲的「可验证」一脉相承。
⑤ 这样做的好处
- 信息永不过时:版本、公告、文档随时可查。
- 路径最短:有链接抓链接、没链接才搜索。
- 限流有冗余:多供应商自动切换。
- 回答可追溯:要求附来源后可逐条核对。
- 能力可控:
websearch: false可在离线 / 保密环境彻底关闭。
⑥ 不这么做的问题 / 坏处
- 本地问题也强行联网 → 被同名不同版本的网上答案带偏,忽略手边真实代码。
- 有 URL 却让 AI 搜索 → 绕路、找错页面、浪费调用。
- 不要求来源 → 无法验证,AI 可能把过时博客当官方结论。
- 只读搜索摘要就采信 → 摘要可能曲解原文,关键决策出错。
⑦ 举一反三:三个例子
例 1(基础):给链接让它读
📌 场景:同事发来一个 RFC 文档链接,让你看看和当前系统是否兼容。
✅ 提示:「读 <url>,列出这份 RFC 的核心机制、与我们现有 X 模块可能冲突的三点,结论附上原文小节标题。」
🔍 讲解:来源明确就用 webfetch,并要求标注原文位置——结论可回到原文核对,这比让 AI 凭记忆谈协议可靠得多。
例 2(进阶):查最新版本 + 交叉验证
📌 场景:你要升级一个依赖,需要知道最新版本有无破坏性变更。
✅ 提示:「联网查某库最新正式版本(不是预发布版),阅读官方发布说明,列出:版本号、破坏性变更、迁移建议;每个结论给官方来源链接。」
🔍 讲解:明确「官方来源」可过滤掉大量质量参差的二手博客;要链接则保证你能点开核对。时效性问题 + 一手来源是联网检索的标准姿势。
例 3(挑战):本地问题不联网,靠证据推理
📌 场景:测试报错,错误栈指向你项目里的 src/auth.ts。
✅ 做法:明确告诉 AI:「先不要上网。读报错栈和 src/auth.ts 相关函数,从代码里找原因,给出最小修复再跑测试。」只有本地证据无法解释(怀疑是上游 bug)时,再让它带着精确错误信息联网查 issue。
🔍 讲解:手边证据充分时,联网搜索只会引入噪音;先穷尽本地证据,把联网作为第二阶段、且带着精确查询词(错误码 / issue 关键词)——先内后外,搜索才精准。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:分别说明什么情况下用 webfetch、什么情况下用 websearch。说出内置的任意两家搜索供应商及其环境变量。
💡 思路提示:有 URL vs 没 URL;Exa/Firecrawl/Parallel/Tavily。
✅ 参考答案:
text
webfetch:已有明确 URL,要读该页面内容时(不抓二进制)。
websearch:要最新信息或不知道来源在哪,按查询词搜索。
四家供应商任选两家:Exa(EXA_API_KEY)、
Firecrawl(FIRECRAWL_API_KEY)、Parallel(PARALLEL_API_KEY)、
Tavily(TAVILY_API_KEY)。🔍 讲解:分清两个工具的信息状态(已知 / 未知来源),就不会用错检索路径。
练习 2(迁移型)
📝 题目:迁移到看病诊断:为什么好医生会「先看你本人的检查报告(本地证据),必要时再查最新医学文献(外部检索)」,而不是一上来就上网搜症状?这对使用 Agent 有什么启发?
💡 思路提示:一手证据优先、外部检索用于补充、带着精确问题查。
✅ 参考答案(示例):
text
- 本人检查报告是针对你病情的一手、精确证据,优先级最高;
- 网上症状信息泛化、质量参差,直接搜容易自我误导;
- 查文献应在掌握具体指标后,带着精确问题检索最新结论。
启发:用 Agent 也应「先读本地代码 / 报错(一手证据),
本地解释不通再联网,且用精确错误信息搜索、核对一手来源」。
检索是证据链的补充环节,而不是跳过思考的捷径。🔍 讲解:证据有层级(一手本地 > 二手网络),检索有顺序(先内后外)。掌握这条通用原则,你就不会让 AI 动辄上网碰运气,而会建立扎实的证据链工作法。
本章小结
| 知识点 | 一句话核心 |
|---|---|
| 1. 工具全景 | 描述结果、让 AI 自选工具;文件 / 命令 / 网络 / 协作四类 inventory |
| 2. Shell 工具 | 权力最大、以你的身份运行;前台 2 分钟超时、长任务走后台、批准前读全命令 |
| 3. 权限系统 | action/resource/effect 三字段;默认 ask、最后匹配生效、deny 优先 |
| 4. MCP 服务器 | 标准化外接能力;local stdio / remote HTTP+OAuth;只装需要的、按 server_tool 授权 |
| 5. 联网检索 | 有 URL 用 webfetch、找最新用 websearch;先内后外、要求来源可核对 |
下一章进入《配置与个性化》:opencode.jsonc 全部关键项详解、主题外观、Formatter、Network 等高级配置,以及怎样把前面积累的设置组织成一套可迁移、可共享的个人配置。