---
title: "07 · 工具、MCP、LSP 与格式化器"
description: "理解 OpenCode 如何连接文件系统、shell、MCP server、LSP 和 formatter。"
verifiedAt: "2026-05-09"
---

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

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

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

## 工具扩展地图

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

```mermaid
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 的工具可以按距离项目核心的远近分层：

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

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

## 2. 内置工具先够用

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

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

官方 Tools 文档说明，OpenCode 内置工具包括 `bash`、`edit`、`write`、`read`、`grep`、`glob`、`lsp`（实验性）、`apply_patch`、`skill`、`todowrite`、`webfetch`、`websearch`、`question`，并且可以通过 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` | 执行中向用户提问 | 适合关键决策点 |

> [!WARNING]
> **文件写入是一组能力**：官方文档说明 `write`、`edit`、`apply_patch` 这类文件修改能力受 `edit` 权限治理。不要只盯着一个工具名，以为禁了 `write` 就万事大吉。

## 3. 权限要先于扩展

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

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

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

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

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

## 4. MCP 适合外部上下文

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

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

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

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

## 5. MCP 本地和远程怎么选

OpenCode 支持本地和远程 MCP。

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

最小配置示例：

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

本地 MCP 示例：

```jsonc
{
  "$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"
      }
    }
  }
}
```

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

```bash
opencode mcp list
opencode mcp auth context7
```

## 6. LSP 的价值

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

适合依赖 LSP 的任务：

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

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

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

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

> [!TIP]
> **LSP 信号要和测试结合**：LSP 适合告诉 agent “哪里有诊断、定义在哪里、引用有哪些”，但不能替代真实构建和测试。

## 7. Formatter 只做机械格式化

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

启用所有内置 formatter：

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

禁用或覆盖某个 formatter：

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

推荐改动流程：

```text
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/`。工具定义可以调用其他语言脚本。

最小只读工具示例：

```ts
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. 工具治理原则

接工具时，按风险逐步推进：

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

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

建议默认规则：

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

## 11. 怎么验收

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

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

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

## 接下来去哪

<Cards>
  <Card title="工具总览" description="查看内置工具、permission、apply_patch、web 工具和 custom tool 的官方边界。" href="/docs/opencode/official/04-tools-mcp/tools" />
  <Card title="连接 MCP" description="需要外部系统上下文时，再按只读、少数、按 agent 开放的原则接入 MCP。" href="/docs/opencode/official/04-tools-mcp/mcp-servers" />
  <Card title="LSP 与格式化器" description="把诊断信号和机械格式化分开，不让 formatter 掩盖逻辑 diff。" href="/docs/opencode/official/04-tools-mcp/lsp" />
  <Card title="安全、分享与团队使用" description="工具接入后，继续收紧权限、密钥、分享和团队 review 边界。" href="/docs/opencode/understanding/08-security-share-team" />
</Cards>

## 官方资料

- Tools：[https://opencode.ai/docs/tools](https://opencode.ai/docs/tools)
- MCP servers：[https://opencode.ai/docs/mcp-servers](https://opencode.ai/docs/mcp-servers)
- LSP Servers：[https://opencode.ai/docs/lsp](https://opencode.ai/docs/lsp)
- Custom Tools：[https://opencode.ai/docs/custom-tools](https://opencode.ai/docs/custom-tools)
- Formatters：[https://opencode.ai/docs/formatters](https://opencode.ai/docs/formatters)
