AI 编程教程中文版
从原理到实战

07 · 工具、MCP、LSP 与格式化器

理解 OpenCode 如何连接文件系统、shell、MCP server、LSP 和 formatter。

Coding agent 的质量不只取决于模型,也取决于它能接触哪些工具。OpenCode 的工具系统把文件系统、shell、MCP server、LSP、formatter 和 custom tools 接到同一个工作流里。

这一篇解决“工具该接到什么程度”的问题。读完以后,你应该能判断:哪些任务只用内置工具就够,什么时候接 MCP,LSP 能帮什么,formatter 应该怎么开,自定义工具什么时候值得写,以及为什么工具越多越要收紧权限。

先给结论:先用内置工具完成读文件、搜代码、改文件、跑测试;只有需要外部系统时再接 MCP;只有项目语言服务可用时再依赖 LSP;formatter 不要掩盖逻辑 diff;custom tool 只封装重复、可验证、边界清楚的项目动作。

工具扩展地图

OpenCode 工具不是平铺清单,而是一组逐步扩大行动范围的能力。

flowchart TB
  Builtin["内置工具<br/>read / grep / edit / bash"] --> LSP["LSP<br/>诊断 / 定义 / 引用"]
  Builtin --> Formatter["Formatter<br/>机械格式化"]
  Builtin --> Custom["Custom Tools<br/>项目专有动作"]
  Custom --> MCP["MCP Servers<br/>外部系统上下文"]
  MCP --> Plugin["Plugins<br/>运行时扩展"]
  Permission["Permission<br/>allow / ask / deny"] --> Builtin
  Permission --> Custom
  Permission --> MCP

  style Builtin fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
  style MCP fill:#fef3c7,stroke:#f59e0b
  style Plugin fill:#fee2e2,stroke:#ef4444
  style Permission fill:#dcfce7,stroke:#22c55e

判断顺序是:内置工具能解决就不要接 MCP,项目命令能明确封装再做 custom tool,需要运行时事件才考虑 plugin。

1. 工具系统先分层

OpenCode 的工具可以按距离项目核心的远近分层:

内置工具       读写文件、搜索、shell、patch、webfetch
LSP           代码诊断、符号、定义、引用、类型信号
Formatter     文件写入后的机械格式化
Custom Tools  项目专有动作
MCP Servers   外部系统和远程上下文
Plugins       运行时生命周期扩展

不要把这些层混成“工具越多越好”。每多接一层,模型可选动作、上下文成本和权限风险都会增加。

2. 内置工具先够用

大多数任务先用内置能力就够:

  • 读取文件。
  • 搜索文件和内容。
  • 修改文件。
  • 应用 patch。
  • 运行 shell 命令。
  • 执行测试和格式化。
  • 获取指定网页内容。
  • 根据命令输出继续修复。

官方 Tools 文档说明,OpenCode 内置工具包括 basheditwritereadgrepgloblsp(实验性)、apply_patchskilltodowritewebfetchwebsearchquestion,并且可以通过 permission 控制。其中 websearch 走 Exa AI 的 MCP 服务,OpenCode 直连,不需要你额外配 API key。

常见内置工具可以这样理解:

工具用途权限建议
read / grep / glob读文件、搜代码、找路径通常允许
edit / write / apply_patch修改文件、新建文件、应用补丁默认 ask,审查类 agent deny
bash运行命令、测试、构建、诊断默认 ask,高风险命令 deny
lsp(实验性)跳定义、找引用、查类型、调用层级通常允许(参第 6 节)
skill按需加载 SKILL.md内部 skill 默认 ask
webfetch / websearch获取网页或搜索外部信息研究类 allow,隐私敏感项目 ask
todowrite维护多步骤任务的待办清单通常允许
question执行中向用户提问适合关键决策点

文件写入是一组能力:官方文档说明 writeeditapply_patch 这类文件修改能力受 edit 权限治理。不要只盯着一个工具名,以为禁了 write 就万事大吉。

3. 权限要先于扩展

官方文档说内置工具默认启用;真实项目里,不应该长期依赖默认开放状态。项目级配置可以先收紧:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "read": "allow",
    "grep": "allow",
    "glob": "allow",
    "edit": "ask",
    "bash": "ask",
    "webfetch": "ask"
  }
}

如果某个 MCP server 暴露了一组工具,可以用通配符控制:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "sentry_*": "ask",
    "github_*": "ask"
  }
}

这比在提示词里写“谨慎操作”可靠。提示词是意图,permission 是执行边界。

4. MCP 适合外部上下文

MCP server 适合把外部系统变成 agent 可调用工具。例如:

  • GitHub issue / PR。
  • 数据库查询。
  • 内部 API。
  • 文档搜索。
  • 设计稿读取。
  • 浏览器自动化。
  • 项目管理系统。

MCP 的价值是让 agent 获取“项目外部上下文”。如果信息已经在本地文件里,就不一定需要 MCP。

MCP 不是越多越好:官方文档提醒,MCP 工具会增加上下文,工具多了可能很快吃掉上下文窗口。GitHub 这类 MCP 往往工具很多,启用前要确认你真的需要。

5. MCP 本地和远程怎么选

OpenCode 支持本地和远程 MCP。

类型适合场景风险点
Local MCP需要本机 CLI、内网、文件系统、项目环境换机器要重配,命令环境可能不一致
Remote MCPSaaS、文档搜索、云服务、团队统一入口OAuth、API key、远程权限和数据边界

最小配置示例:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "context7": {
      "type": "remote",
      "url": "https://mcp.context7.com/mcp",
      "enabled": true
    }
  }
}

本地 MCP 示例:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "my-local-server": {
      "type": "local",
      "command": ["npx", "-y", "my-mcp-command"],
      "enabled": true,
      "environment": {
        "MY_ENV_VAR": "my_env_var_value"
      }
    }
  }
}

先用只读问题验证,再考虑写入型工具。常用检查命令:

opencode mcp list
opencode mcp auth context7

6. LSP 的价值

LSP 给 agent 提供更接近 IDE 的代码理解能力,包括符号、诊断、跳转和类型信息。对大型代码库来说,这比单纯全文搜索更可靠。

适合依赖 LSP 的任务:

  • 找函数定义和引用。
  • 判断类型错误。
  • 理解跨文件调用关系。
  • 修复编译诊断。
  • 做局部重命名或接口调整。

官方 LSP 文档说明,OpenCode 内置了多种语言服务器集成。满足文件扩展名和依赖要求时,相关 LSP server 会启动;也可以通过 lsp 配置禁用、定制命令、环境变量和初始化选项。

{
  "$schema": "https://opencode.ai/config.json",
  "lsp": {
    "typescript": {
      "initialization": {
        "preferences": {
          "importModuleSpecifierPreference": "relative"
        }
      }
    }
  }
}

但 LSP 不是万能。项目依赖没装好、语言服务器没启动、monorepo 配置复杂时,LSP 信息也可能不完整。关键改动仍要靠测试、类型检查和人工 review 验证。

LSP 信号要和测试结合:LSP 适合告诉 agent “哪里有诊断、定义在哪里、引用有哪些”,但不能替代真实构建和测试。

7. Formatter 只做机械格式化

Formatter 适合做机械格式化,不适合掩盖逻辑问题。官方文档说明,formatter 默认是禁用的,需要在配置里启用。

启用所有内置 formatter:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": true
}

禁用或覆盖某个 formatter:

{
  "$schema": "https://opencode.ai/config.json",
  "formatter": {
    "prettier": {
      "disabled": true
    }
  }
}

推荐改动流程:

1. 让 agent 完成最小代码改动
2. 跑测试或类型检查
3. 再运行 formatter
4. 检查 diff 是否只包含预期范围

不要一开始就全仓库格式化。大范围格式化会淹没真实逻辑 diff,也增加回滚风险。

8. Custom Tools 什么时候需要

当一个 shell 命令反复使用,并且输出需要被 agent 稳定解释时,可以封装成 custom tool。

适合封装的例子:

  • 查询内部服务状态。
  • 运行项目专用诊断。
  • 读取结构化配置。
  • 生成固定格式报告。
  • 调用公司内部 API。

官方 Custom Tools 文档说明,工具定义用 TypeScript / JavaScript 文件,放在 .opencode/tools/~/.config/opencode/tools/。工具定义可以调用其他语言脚本。

最小只读工具示例:

import { tool } from "@opencode-ai/plugin";

export default tool({
  description: "Return current project directory information",
  args: {},
  async execute(args, context) {
    return `directory=${context.directory}\nworktree=${context.worktree}`;
  },
});

不要把危险操作封装成“一键执行”的工具,例如删除数据、发布生产、重置数据库。即使封装,也必须加确认、dry-run、参数校验和权限边界。

9. 怎么决定用哪一层

可以按这个顺序判断:

需求优先方案
读文件、搜代码、跑测试内置工具
需要代码诊断、定义、引用LSP
需要保持风格一致Formatter
需要调用项目专有动作Custom Tool
需要外部系统上下文MCP
需要改变 OpenCode 生命周期Plugin

不要用 MCP 解决本地 grep 能解决的问题,也不要用 custom tool 包装一次性命令。工具进入 OpenCode 后,就会变成模型可能调用的能力,需要长期维护。

10. 工具治理原则

接工具时,按风险逐步推进:

本地只读工具
本地可写工具
项目测试/检查工具
MCP 只读外部工具
MCP 可写外部工具
发布/生产工具

每往后一层,权限和审计要求都要更严格。

建议默认规则:

  • 只读工具可以更开放。
  • 写文件和 bash 默认 ask
  • 外部写入 MCP 默认 askdeny
  • 生产、发布、删除、数据库写入不要自动允许。
  • 全局工具少放,项目工具先验证。
  • 工具输出要短,避免把日志和敏感信息塞进上下文。

11. 怎么验收

你可以用 6 个问题检查工具体系是否过关:

#问题自检
1内置工具能解决的问题,是否没有额外接 MCP?
2写文件、bash、外部系统写入是否有 permission 边界?
3MCP 是否只启用了真正高频的 1-3 个?
4LSP 诊断是否通过测试或类型检查验证过?
5Formatter 是否没有扩大无关 diff?
6Custom tool 是否只读起步,参数和输出都可控?

过关标准:你能解释每个工具为什么存在、谁能调用、是否会写入外部系统,以及出问题时如何关闭它。

接下来去哪

官方资料

本页目录