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 是否只讀起步,引數和輸出都可控?

過關標準:你能解釋每個工具為什麼存在、誰能呼叫、是否會寫入外部系統,以及出問題時如何關閉它。

接下來去哪

官方資料

本頁目錄