跳轉到主要內容
這個單元解決什麼問題能用 CLI 完成的事,優先用 CLI;MCP 是 fallback,不是預設。這個單元講 CLI 與 MCP 的本質差異:token 成本、可組合性、可審計性、認證與狀態管理,解釋為何 CLI-first 是更穩健的預設策略,並給出「什麼條件才退回 MCP」的明確判準。最後用同一個工作流的 CLI vs MCP 對照 worked example 把差異量化。

學習目標

  • 講清 CLI 與 MCP 在 token 成本、可組合性、可審計性、認證與狀態管理上的本質差異。
  • 說出 CLI-first 策略的理由,並舉出具體的可組合性優勢(pipe、--jsonjq 串接)。
  • 判斷何時應 fallback 到 MCP(CLI 不可用、未認證、rate limit、無 CLI 對應)。
  • 避免同一操作同時走 CLI 與 MCP,避免結果分裂與 token 浪費。

1. CLI 與 MCP 各是什麼

CLI(Command Line Interface)是既有的命令列工具:gitghdockerkubectlpsqlawsnpmuvmakejq 等。呼叫後直接輸出到 stdout / stderr,不需要額外協定層。 MCP(Model Context Protocol)是 2024 年由 Anthropic 提出的開放標準,定義「外部工具與資料源如何被 LLM 結構化地呼叫」[1]。MCP server 對外暴露 tools / resources / prompts 三類介面;MCP client(如 Claude Code、Cursor)連上後把工具掛入自己的 mcp__<server>__<tool> 命名空間。 兩者的角色定位差異:
CLIMCP
本質工具本身工具接入的中間層協定
主要消費者人(鍵盤)+ agent(透過 Bash tool)agent(MCP client)
互通性跨工具、跨語言、跨作業系統跨支援 MCP 的 client,但 server / client 矩陣仍在收斂
成熟度數十年兩年多,仍在規格演進
Claude Code 對 Bash tool 的設計Claude Code 把 Bash 列為核心工具類型之一(與檔案修改、唯讀並列三層)[2]。lscatgrepfindwcwhichgit status 等唯讀指令內建免 prompt [2];其他指令走 Bash(specifier) 形式的 allow / deny / ask 規則。這個設計本身就把 Bash 放在最常用、最高優先的位置。

2. 本質差異

2.1 Token 成本

MCP 的固定 context 成本:MCP server 連線後,其工具描述(tool schema)會進入模型 context。即便 tool search 預設開啟讓 schema 延後載入,已被 Claude 發現的 tool 仍佔用對話輪次的 context [1]。 CLI 的可變 context 成本:CLI 沒有預載的 schema。Bash tool 的 schema 是固定的、不隨你跑了什麼指令而變大。真正的成本只在 stdout 進入 context 的那一刻,而 stdout 是你可控的(用 headtailjq -c '.[0]' 預先裁剪)。 實測估算(粗略,量級用):一個簡單 MCP 工具呼叫的單次 token 成本包含「schema 觸發 + 結構化 JSON 回應」兩個部分;同等的 CLI 呼叫,schema 成本是 0,回應可以裁到只剩一行 JSON。對 200k 脈絡視窗,差距看起來小;對一天跑幾十次的工作流,每月差距是數萬 token 級別。

2.2 可組合性

CLI 是 shell-native:每個 CLI 的輸出可被另一個 CLI 透過 pipe 串接,形成高密度資訊萃取。
# 找出本月(createdAt 在 2026-05 之後)review 數超過 5 的 PR
gh pr list --state all --json number,createdAt \
  | jq -r '.[] | select(.createdAt > "2026-05-01") | .number' \
  | xargs -I{} gh pr view {} --json number,reviews \
  | jq -r 'select((.reviews | length) > 5) | .number'
MCP 沒有等價的 shell-level 串接:每次 mcp__<server>__<tool> 呼叫獨立,輸出回 context 後 Claude 決定下一步。一個跨四步的 pipeline 會吃四次 schema 觸發、四次完整回應。

2.3 可審計性

CLI 指令明文可見、可記錄於 shell historyauditdsyscall、bash history 都能稽核。CI 環境下 git log 內的 run: 段也是確定性紀錄。 MCP 呼叫在 agent 執行層,需要額外日誌機制(Hook、Subagent log)才可追蹤(04-6 Hooks 提供部分支援,但不是預設)。對合規需求高的場景(金融、醫療、學術審查),CLI 的可審計性是結構性優勢。

2.4 認證與狀態管理

CLI 沿用作業系統層級認證gh auth loginaws configuregcloud auth login 把 token 存進 OS keychain 或 ~/.config 對應目錄;後續指令自動帶認證。Claude Code 的 Bash tool 對認證檔的讀取權限可由 permissions.deny 細部管控 [2]。 MCP 認證是各 server 自己的事:HTTP server 走 OAuth(04-9 MCP 整合 詳述);stdio server 透過 env 傳 key;多數 server 沒有 session 狀態,但部分(如 Notion 編輯、Atlassian 變更)有。狀態管理更複雜,需要個別 server 理解。

3. 為何 CLI-first

把上面的差異收斂成四個具體理由:
  1. CLI 是該生態的官方正規用法gh 是 GitHub 官方 CLI、kubectl 是 K8s 官方 CLI、aws 是 AWS 官方 CLI。文件完整、版本穩定、社群覆蓋廣、與上游版本同步。繞過它等於繞過一條已經有人維護的正路。
  2. 輸出格式可控gh pr list --json number,title,state 精準到欄位;MCP 呼叫回傳整個結構化物件,你要的欄位與不要的欄位都進 context。
  3. 不額外吃 context。Bash tool schema 是固定的;MCP 工具描述隨 server 數量線性增加。
  4. 除錯路徑清晰。CLI 失敗有明確 exit code 與 stderr;MCP 失敗的診斷路徑因 server 而異(協議錯誤、認證過期、工具不存在都不同)。
沒有官方明文「CLI first」指引截至 2026-06,Anthropic 官方文件並未在 [permissions] 與 [MCP] 章節使用「CLI first」字樣 [1, 2]。「CLI 優先」是本 Playbook 從官方架構推導出來的實務策略:Bash 是核心工具類型、唯讀指令免 prompt、權限精細到指令前綴。這些設計本身就把 Bash 放在最高槓桿位置,CLI-first 是順著這條路走。

4. 何時用 MCP(fallback 觸發條件)

CLI-first 是預設。只有滿足下列任一條件才切換到 MCP:
觸發條件範例
該服務根本沒有 CLI多數 SaaS(Notion 早期、Linear、Sentry 部分功能)只提供 REST API
CLI 需認證,但 agent 環境無法完成OAuth 流程必須互動、不能用 device code flow
CLI 已達 rate limit多個 client 共用同一組 token;MCP server 可有獨立的 token pool
需要跨多個 MCP client 統一同一個 server 給 Claude Code 與 Cursor 共用,避免在兩處各寫一份
該操作需要結構化、型別化的回應schema 驗證是 MCP 設計目標之一
不是「MCP 也可以,兩個都試試」fallback 觸發規則:任一條件明確成立才切換。不要「看起來 MCP 也行、就裝一個」,多裝一個 server 永遠有 context 成本、權限面、供應鏈風險。一個工作流選定一條路,切換後不回頭混用(下節)。

5. Worked example:同一操作走 CLI 與走 MCP

5.1 情境

查詢某 GitHub repo 的最新 10 筆 open PR,列出編號、標題、作者、是否為 draft。

5.2 CLI 路徑

gh pr list --repo owner/repo --state open --limit 10 \
  --json number,title,author,isDraft \
  | jq -r '.[] | "\(.number)\t\(.title)\t\(.author.login)\tdraft=\(.isDraft)"'
特性:
  • stdout 一次輸出,可直接 | head| wc -l| column -t 後處理。
  • 失敗時 exit code 非 0,stderr 明確(「API rate limit exceeded」、「auth required」)。
  • token 成本:0 schema 載入 + 約 800 token 結構化輸出(10 筆 PR 的 JSON)。
  • 對 Claude 而言,Bash tool 的 schema 早已常駐,不會因這次呼叫而增加。

5.3 MCP 路徑

假設已裝 GitHub 官方 MCP server(mcp__github__list_pull_requests):
呼叫 mcp__github__list_pull_requests(owner='owner', repo='repo', state='open', per_page=10),回傳後摘要
特性:
  • tool schema 進入 context(tool search 預設開啟所以是觸發時載入,但載入就要佔 context)。
  • 回傳是完整結構化物件(可能含 headbaseuser 等你用不到的欄位),通常 1,500-3,000 token。
  • 你要「draft 狀態」這種衍生欄位,要 Claude 在 context 內再運算一次。
  • 失敗時的錯誤訊息因 server 設計而異,部分 server 對人類不友善。

5.4 對照重點

面向CLI(ghMCP(mcp__github__*
Schema 載入成本0(共用 Bash tool schema)每次 server 連線觸發時載入
單次回應 token約 800(裁切後可更低)約 1,500-3,000(完整物件)
可組合性可 pipe / jq / xargs / 進檔案須 Claude 在 context 內運算
可審計性shell history / git log / auditd需 Hook 或 server log
除錯明確 exit code + stderr依 server 實作
認證gh auth login 一次永久OAuth 流程每次 token 過期重來
量化評估假設一天跑這個查詢 50 次:CLI 路徑每月多燒約 0.6M token(回應部分);MCP 路徑每月多燒約 2.3M token(schema + 回應)。在 Claude Sonnet 4.6 級別的定價下,每月差距是數美元級。但疊上多個 server 後,差距是數十美元級。CLI-first 不只是省 token,也是省 context 預算給真正重要的事。

6. 反模式:CLI 與 MCP 混用

最常見的隱性 bug 來源。具體場景:
# 你手動在 shell 跑:建立 PR
gh pr create --base main --head feature-x --title "WIP" --body "..."
同一時間,agent 接到「幫我建立 PR」指令,不知道你手動建了,於是又用 MCP 走:
mcp__github__create_pull_request(...)
結果:兩個 PR 並存、訊息不一致、gh 端的 CI 跑了一次、MCP 端的 CI 又跑了一次。狀態分裂。 規則:
  1. 一個操作選定一條路:今天用 CLI 就 CLI、用 MCP 就 MCP,整個 session 一致。
  2. fallback 切換後不回頭:CLI 不可用才切 MCP,不要「兩邊都試看看哪個行」。
  3. 跨 session 也要標明:在 CLAUDE.md 寫「本專案統一用 gh CLI,不裝 GitHub MCP server」,給 session 一致的預設。

7. 工具對照

概念Anthropic Claude(主範本)OpenAI CodexGoogle AntigravityGitHub Copilot CLICursor(短提)
官方 CLIclaude CLI(Claude Code)[1]codex CLIagy(Antigravity)gh + Copilot CLI extensioncursor CLI
Bash 工具支援核心工具(內建免 prompt 唯讀指令)[2]設定式設定式設定式設定式
MCP 支援內建 MCP client,.mcp.json 設定 [1]設定式 [需確認原始出處]設定式 [需確認原始出處]設定式 [需確認原始出處]內建 [需確認原始出處]
認證管理OS keychain + ANTHROPIC_API_KEY 環境變數 + gh 等子 CLI 自帶設定式設定式設定式設定式
Token 預算控制tool search 預設開啟 [1]設定式設定式設定式設定式
CLI-first 策略官方指引隱含(Bash 為核心工具)[2]無明文無明文無明文無明文
命名澄清Claude Code 的 Bash tool 是 agent 呼叫 shell 的介面;claude CLI 是呼叫 Claude Code 本身的命令。兩者層級不同。OpenAI Codex、Antigravity、GitHub Copilot CLI 對 Bash tool 與 MCP 的細節以各家當前官方文件為準;上表「需確認原始出處」項目需查證。Cursor 為第三方 IDE(Anysphere),本 Playbook 僅短提一欄。

動手做

30 分鐘練習
  1. 建 CLI-first checklist(10 分鐘):列出你工作流中常見的 10 個操作(查 issue、查 PR、跑測試、看 log、查 DB、deploy 等),逐一標記「有 CLI 可用」「需 MCP fallback」「內建工具就夠」。這份清單是下個 session 開工的預設。
  2. 同一操作雙路對照(15 分鐘):選一個你常用的操作(如查 GitHub issue),先用 CLI 完成(記下 token 估算:用 wc -wwc -c 大致估算 stdout 大小),再用 MCP 完成(看 context 中實際佔多少 token)。差距量化,決定哪一條作為預設。
  3. 混用偵測(5 分鐘):翻 ~/.bash_history 與最近 session 的 transcript,找出有沒有 CLI 與 MCP 並存呼叫同一服務的痕跡。標記、決定要不要統一。

常見誤區

反模式清單
  • 以為「MCP 是 AI-native 的更現代做法」就預設用 MCP:忽略 CLI 在可組合性與 token 成本上的結構性優勢。新不等於更適合你的場景。
  • CLI 可用,但 MCP 設定已存在就懶得切換:導致 context 浪費。設定存在不構成預設,每次新操作都過 fallback 觸發條件。
  • 同一 session 內 CLI 與 MCP 並存呼叫同一服務:狀態不一致的隱性 bug 來源。統一一條路。
  • Bash tool 當萬靈丹,連簡單的 grep 都包成 MCP server:shell 早就會做的事,硬包成 MCP 等於把簡單的事複雜化。CLI-first 的相反極端也要避免。
  • fallback 切換沒在 CLAUDE.md 標明:下個 session 又是新猜測。寫進規則檔。
  • gh pr listmcp__github__list_pull_requests 視為完全等價:它們的 token 成本、可審計性、除錯路徑都不同。等價是錯覺。

自我檢核

通過本單元的標準
  1. 面對一個新的整合需求,你能在 30 秒內判斷「CLI 可用還是需要 MCP」嗎?說出判斷依據。
  2. 你能否列出至少三條 CLI 相對 MCP 的具體優勢?每條配一個真實例子。
  3. 你目前 session(或最近一個 session)有沒有 CLI 與 MCP 混用同一服務的情況?列出、決定要不要統一。
  4. 你的 CLAUDE.md 有沒有寫明 CLI-first 偏好?若沒有,現在補一段。

來源與延伸閱讀

事實主張依官方文件,快變動項標註截至 2026-05。
  • [1] Anthropic, “Connect Claude Code to tools via MCP,” code.claude.com, 2026. [Online]. Available: https://code.claude.com/docs/en/mcp (截至 2026-06;MCP transport、scope、tool search)
  • [2] Anthropic, “Configure permissions,” code.claude.com, 2026. [Online]. Available: https://code.claude.com/docs/en/permissions (截至 2026-06;Bash tool 為核心工具、唯讀指令清單、allow / deny / ask 規則的 Bash(specifier) 形式、shell 識別子指令)