OpenCode 提供了一套豐富的內建工具,讓代理能夠讀取、寫入、搜尋、編輯檔案,執行命令,以及與外部服務互動。這些工具是代理與開發環境互動的基本介面。
| 工具名稱 | 功能說明 | 常用場景 |
|---|---|---|
bash |
執行 shell 命令 | 編譯、測試、git 操作、啟動服務 |
edit |
字串替換編輯檔案 | 精確修改既有檔案內容 |
write |
寫入新檔案 | 建立新檔案、重置檔案內容 |
read |
讀取檔案內容 | 瀏覽原始碼、檢查設定檔 |
grep |
正則表達式內容搜尋 | 找出特定模式、跨檔案搜尋 |
glob |
檔案名稱模式匹配 | 尋找特定命名規則的檔案 |
lsp_diagnostics |
取得 LSP 診斷資訊 | 檢查語法錯誤、型別錯誤 |
patch |
應用 diff 修補檔 | 批次修改多個位置 |
skill |
載入領域技能 | 啟動特定任務的專用指引 |
todowrite |
管理工作項目清單 | 建立與追蹤待辦事項 |
webfetch |
擷取網頁內容 | 讀取 API 文件、線上手冊 |
websearch |
網路搜尋 | 查詢技術問題、最新資訊 |
question |
向使用者提問 | 需求釐清、決策確認 |
OpenCode 的權限系統讓開發者精確控制每個工具的行為,在便利性與安全性之間取得平衡。每個工具都可以設定三種權限等級:
代理可以自由使用此工具,無需詢問使用者。適合安全且頻繁使用的工具,如 read、grep。
代理每次使用工具時都需要獲得使用者明確許可。適合有潛在風險的工具,如 bash、write。
完全禁止代理使用此工具。適用於不應自動化的操作,或特定專案中禁止的操作。
權限設定位於 opencode.json 的頂層 tools 欄位:
{
"tools": {
"bash": {
"*": "ask",
"git *": "allow",
"npm *": "allow",
"rm -rf *": "deny"
},
"write": {
"*": "ask",
"src/**": "allow"
},
"edit": {
"*": "ask",
"*.md": "allow"
},
"read": {
"*": "allow"
},
"websearch": {
"*": "allow"
},
"webfetch": {
"*": "ask",
"api.github.com/*": "allow"
}
}
}
| 規則 | 效果 | 說明 |
|---|---|---|
"bash": { "git *": "allow" } |
允許 git 命令 | 代理可自由執行 git 相關操作 |
"bash": { "rm -rf *": "deny" } |
禁止刪除命令 | 防止代理意外刪除檔案 |
"write": { "src/**": "allow" } |
允許寫入原始碼 | 代理可自由編輯 src 目錄下的檔案 |
"write": { "*": "ask" } |
其他寫入需詢問 | 非 src 目錄的寫入需使用者確認 |
"edit": { "*.md": "allow" } |
允許編輯文件 | 代理可直接修改 markdown 文件 |
DROP TABLE、rm -rf、force-push),建議明確設定為 deny 或至少 ask。此外,可以搭配 /careful 命令啟用全域安全護欄。
除了簡單的字串匹配,OpenCode 的權限系統還支援更精細的物件語法,允許根據工具參數的具體內容進行判斷:
{
"tools": {
"bash": {
"rules": [
{
"match": { "command": "git push --force *" },
"permission": "deny",
"reason": "禁止強制推送,可能造成歷史遺失"
},
{
"match": { "command": "npm publish *" },
"permission": "ask",
"reason": "發佈套件需要人工確認"
},
{
"match": { "command": "git *" },
"permission": "allow"
}
]
}
}
}
這種語法讓權限管理變得極具彈性——你可以針對特定命令參數、檔案路徑、或任何工具輸入內容設定不同的權限策略。
語言伺服器協定(Language Server Protocol, LSP)是 OpenCode 提供即時語法檢查與型別診斷的關鍵技術。每當代理編輯檔案後,OpenCode 會自動查詢 LSP 伺服器獲取診斷結果,並將這些發現回饋給代理,形成閉迴路修正。
OpenCode 內建支援以下語言的 LSP 伺服器,無需額外外掛:
typescript-language-server — 最完整的型別檢查與重構支援
python-lsp-server (pylsp) — 語法檢查、自動完成、重構
rust-analyzer — 完整的 Rust 語言支援
eclipse-jdtls — Eclipse JDT 語言伺服器
ruby-lsp — Ruby 語言伺服器
php-language-server — PHP 智慧編輯支援
| 語言 | LSP 伺服器 | 識別名稱 |
|---|---|---|
| TypeScript | typescript-language-server | typescript |
| JavaScript | typescript-language-server | javascript |
| Python | python-lsp-server | python |
| Rust | rust-analyzer | rust |
| Go | gopls | go |
| Java | eclipse-jdtls | java |
| Ruby | ruby-lsp | ruby |
| PHP | php-language-server | php |
| C# | csharp-ls | csharp |
| C/C++ | clangd | clangd |
| Dart | dart-language-server | dart |
| Deno | deno-lsp | deno |
| Swift | sourcekit-lsp | swift |
| Kotlin | kotlin-language-server | kotlin |
| Lua | lua-language-server | lua |
| SQL | sql-language-server | sql |
| Bash | bash-language-server | bash |
| Astro | astro-ls | astro |
| Svelte | svelte-language-server | svelte |
| ESLint | eslint-lsp | eslint |
每個 LSP 伺服器都可以在 opencode.json 中進行細部設定:
{
"lsp": {
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"],
"extensions": [".ts", ".tsx", ".js", ".jsx"],
"priority": 10,
"env": {
"NODE_OPTIONS": "--max-old-space-size=4096"
}
},
"python": {
"command": "pylsp",
"extensions": [".py"],
"priority": 5,
"settings": {
"pylsp.plugins.pyflakes.enabled": true,
"pylsp.plugins.mccabe.enabled": false
}
},
"rust": {
"command": "rust-analyzer",
"extensions": [".rs"],
"priority": 10,
"settings": {
"rust-analyzer.checkOnSave": true
}
}
}
}
| 設定項 | 說明 | 預設值 |
|---|---|---|
command |
LSP 伺服器的執行檔路徑或名稱 | — |
args |
啟動參數 | ["--stdio"] |
extensions |
此 LSP 關聯的副檔名列表 | — |
priority |
當多個 LSP 支援同一語言時的優先權(越高越優先) | 0 |
env |
環境變數覆蓋 | {} |
settings |
傳遞給 LSP 伺服器的初始化設定 | {} |
priority 設定來控制當多個 LSP 競爭同一語言時的選擇。
除了內建工具,OpenCode 提供了自訂工具 API,讓開發者可以建立專屬的工具來擴充代理的能力。自訂工具透過 OpenCode SDK 開發,並在 opencode.json 中註冊。
{
"customTools": [
{
"name": "send-slack-notification",
"description": "發送通知到 Slack 頻道",
"schema": {
"type": "object",
"properties": {
"channel": { "type": "string", "description": "目標頻道名稱" },
"message": { "type": "string", "description": "要發送的訊息內容" }
},
"required": ["channel", "message"]
},
"handler": "tools/slack-notifier.js"
}
]
}
權限規則是「依序比對,先匹配先採用」。OpenCode 會按照 rules 陣列中的順序逐一檢查每個規則。如果某個規則的 match 模式與實際工具呼叫相符,就採用該規則的 permission 值。若沒有任何規則匹配,則使用該工具的全域設定;若連全域設定都沒有,預設為 ask。這表示你可以先放入精確的特殊規則,再放入通用的 catch-all 規則。
首先確認 LSP 伺服器已經安裝在系統上(例如 npm install -g typescript-language-server)。若已安裝仍無法啟動,可以在 opencode.json 的 LSP 設定中指定完整的命令路徑。若使用的是 env 設定環境變數,請確認變數名稱正確。最後,可以檢查 OpenCode 的日誌輸出(通常位於專案目錄下的 .opencode/logs/)獲取詳細的錯誤資訊。
兩者的主要差異在於使用範圍與通訊協定。自訂工具是定義在 opencode.json 中的本機工具,僅在目前專案中可用,適合簡單的腳本整合(如發送 Slack 通知、呼叫內部 API)。MCP 伺服器則是遵循 Model Context Protocol 的獨立服務,可以跨專案共用,支援遠端執行、OAuth 認證等進階功能,適合需要共用或需要複雜初始化的工具。第 11 章會詳細介紹 MCP 的設定與使用。