跳到主要內容

【2026 最新】MCP vs CLI 誰真的省 Token?同任務 A/B Test 拆解 Harness Tax

最後更新: ·
MCP vs CLI Token A/B Test 教學首圖,native typed tools 與 CLI façade 連到同一 MCP backend,拆解 Harness Tax

MCP vs CLI 到底誰比較省 Token?你可能看過兩種完全相反的答案:一派說 MCP 把整本工具說明書塞進 context,還沒開始工作就先燒掉幾萬 token;另一派則說 typed tools 能減少猜參數、重試與錯誤,最後反而更省。

這個痛點不是紙上談兵。2026 年 8 月 11 日的 mcptoon Show HN,截至 8 月 12 日已超過 60 points、共有 41 comments;同週一位 r/mcp 實作者自述,某個 186-tool GitLab 設定約有 168 kB JSON Schema,粗估約占 40K tokens。後者沒有附 tokenizer、原始 schema 與 client 版本,所以只能當需求訊號,不能改寫成「一台 MCP server 固定吃 40K」。

更關鍵的是,8 月 9 日出現一份 涵蓋 7 種 Agent scaffolding、5 個模型的公開研究(並非完整 7×5 全因子):它報告的結果沒有支持「MCP 天生比較貴」或「CLI 一定更省」,反而把焦點拉回包住模型的 Harness。不過 AlphaLab 檢查公開程式碼後也找到驗收污染與 credential 隔離缺口,因此本文會把數字當成待驗證的線索,不當成乾淨因果結論。接下來用一個六步 repository 任務,從零搭出更嚴格、可在自己 repo 重跑的 paired A/B Test。

Table of Contents

先說結論:MCP vs CLI 比的不是招牌,而是整台機器

🧪 記憶把手:Context 負載=固定前綴+動態 schema/result/transcript+失敗重跑流量;帳單則按 provider 的 usage 欄位各自計價。
Cache read/write 可能改變費率,卻不會把已進入 request 的內容從 context 扣掉。這裡把 scaffold/harness 都當成包住模型、替它送 prompt、掛工具、跑 loop 的執行層。

  • 不能直接下結論:論文報告的 13 組 paired MCP÷CLI 比值從 0.43× 到 29.06×,中位數 0.93×;公開 harness 又有隔離缺口,不能把它讀成固定 penalty。
  • 先比完成,再比省:只計算便宜卻沒完成的 run,等於把「沒做完」誤當成節省。
  • 一定要驗證工具路徑:把 MCP 接上不代表 Agent 真的用 MCP;一句「請用 MCP」也擋不住它偷走 shell、HTTP API 或其他 built-in tool。
  • 先拆兩個軸:model_surface 是 typed tools 或 shell/CLI;backend_path 才是 MCP、直接 API 或本機 process。若走 MCP,再另記 mcp_transport 是 stdio 或 Streamable HTTP。
  • 最後通常是三選一:窄而成熟的任務偏 CLI;需要 typed inputs、動態 discovery 或跨服務整合時偏 MCP;工具很多但每次只用少數時,偏向 lazy/compressed MCP。
MCP vs CLI Harness Tax 雙層帳:Context 負載與 provider 帳單成本要分開計算
Context occupancy 與 billed usage 是兩本帳;cache 可能打折,不代表內容沒占 context。

MCP vs CLI 差在哪?先把兩條路畫清楚

先把模型想成一位坐在工作桌前的工程師。MCP 像每項工具都附上有型別的操作卡:名稱、用途、參數與 JSON Schema 都寫清楚,模型可以發出結構化呼叫。CLI 則像只給它一個 shell,再告訴它 gitghrgjq 已安裝;模型靠訓練時學過的命令與 --help 完成工作。

兩者都不是「零工具說明」。CLI 仍要帶 shell 與檔案工具的 schema,MCP 也不必然把每個遠端工具全文塞給模型。最新版 MCP 2026-07-28 Tools 規格明確寫道:實作可以自行決定如何把工具呈現給使用者與模型;tools/list 也支援 pagination 與 caching。換句話說,「全部 schema 每回合重送」是某些 client 的 delivery choice,不是協定強迫的唯一做法

這也是為什麼問題不能只寫成「MCP vs CLI」。同一個 MCP server,可以被 client eager-load 44 個 schema,也可以先給一個搜尋/gateway tool,需要時才展開 1 個完整 schema;同一個 CLI,也可能先用 jq 把 20 筆 issue 壓成三個欄位,或把整包 JSON 原封不動塞回 context。介面是入口,Harness 才決定行李怎麼打包。

公平實驗因此要把兩個軸分開:model_surface 記錄模型看到 native typed tools 還是 shell/CLI;backend_path 記錄背後走 MCP、直接 API 還是本機 process。若路徑是 MCP,再記 mcp_transport 為 stdio 或 Streamable HTTP。mcptoon 雖讓模型輸入 CLI,但它的 discovery 與 call 流程分別仍透過 MCP initialize/tools/list/tools/call,且固定使用 2024-11-05 handshake;這證明 surface 與 backend path 是兩個軸,不代表它已支援全部 2026-07-28 server。

本文的主實驗會固定同一個持久 broker、MCP server、connection lifecycle 與 canonical result payload:A arm 把能力暴露成 native typed tools;B arm 只給 shell,透過自製 repoctl CLI façade 呼叫同一個 broker。第一輪不做 TOON、欄位裁切或重新包裝,只估模型表面差。之後才加做「CLI full vs filtered」與「MCP eager vs progressive discovery」,把 projection、schema delivery 與 bundled-client overhead 分開。

Harness Tax 的 4 筆帳:你到底在付什麼?

① 固定前綴:Agent 每次出門都背的背包

System prompt、developer instructions、permission policy、built-in tools、skills 索引與 scaffold 控制語句,常在第一個使用者字出現前就已存在。請保存每個 serialized component 的原文、bytes、token count 與 SHA-256。第一個 request 的 total input 還含 user task 與 wrapper;最多只能當 upper-bound baseline,或先減掉兩邊以同一 tokenizer 計算的相同 task payload。

② 工具目錄:一次載入,還是每回合重送?

MCP tool definition 通常包含名稱、description 與 input schema。成本不只看工具數,還要看每一個 model request 實際帶了多少 schema、多少 bytes、估算多少 tokens。如果 client 支援 lazy discovery,另外記錄何時從名稱索引展開完整定義。只看 server 有幾個工具,仍不知道模型看見了多少。

③ Transcript 與結果:工具回來的貨,也要塞進車廂

工具輸出可能比 schema 更肥。CLI 的 --json 結果若沒先經 jq 投影,一樣會灌滿 context;MCP typed result 若由執行環境先 filter、join、aggregate,只把必要欄位交給模型,也可以很省。Anthropic 的 Code execution with MCP 就示範了按需讀取 tool definition、在執行環境過濾資料,再只把小結果送回模型的做法。

④ 失敗與重試:沒完成的 run 也會留下帳單

Agent 猜錯參數、走錯工具、卡在 permission、重複讀檔,甚至自稱完成但 repository 沒變,都已經消耗 token。最實用的總指標不是「最低單次 token」,而是每次通過驗收的成本全部 run 花費 ÷ 通過 run 數。再另外報告 failure cost share:失敗 run 花費 ÷ 全部花費

新研究真正發現什麼?先讀懂 4 個數字

這份研究用一個 private GitHub repository 任務,讓實際採用的 27 種 scaffold/model 組合執行六個操作。MCP arm 使用 44 個 GitHub MCP tools,CLI arm 使用 shell、gitgh。研究公開了 v1.0.0 measurement harness 與逐 run dataset。最重要的不是抓一個倍數當標題,而是看懂哪些只是觀察、哪些仍混著其他變因。

⚠️ AlphaLab 程式碼複核:公開 reset 只關閉 open PR,但 verifier 會抓全部歷史 PR,而 pr_opened 只檢查清單是否非空;舊 PR 因此可能替新 run 得分。另一邊,MCP arm 的 Agent process 仍繼承 GitHub PAT部分完成列又大量使用 shell/curl。所以下列都是論文報告值,不是純介面效果;尤其 29.06× outlier 不能叫作「純 MCP 路徑」。

MCP vs CLI 公開研究摘要:paired ratio、失敗成本、schema delivery 與程式碼複核警告
論文報告值的快照;公開 v1.0.0 harness 有驗收與 credential 隔離缺口,不能當成 MCP/CLI 的乾淨因果估計。
  • Scaffolding 差異很大:論文報告的 completed-run scaffold medians 從 14,660 到 288,808 input tokens,約 20×;但模型組合與 scaffold 功能並不相同,這是 observed spread,不是 Harness Tax 的因果估計。
  • 介面方向不穩:13 組同 scaffolding、同模型且兩邊都完成的 paired ratio,MCP÷CLI 從 0.434× 到 29.056×,中位數 0.934×。加上實際路徑污染後,最安全的讀法是「目前證據不足以給介面一個固定 penalty」。
  • 失敗次數相同,失敗價格不同:主矩陣兩邊都完成 16/19,重複資料也都完成 25/29;論文模型化成本中,失敗花費占比是 MCP 12.9%、CLI 2.2%。這是尾端成本線索,不是 MCP 必然較危險的證明。
  • Delivery method 是候選機制:Hermes 每輪共帶 7 個 model-facing schema(含 2 個 gateway);其餘四個 eager clients 每輪帶完整 44 個 GitHub MCP schema,另加各自 built-ins。論文分組後報 70,836 vs 216,986(約 3.1×),但只有 Hermes on-demand,模型、scaffold 與可觀測路徑也不同,不能歸因於 delivery。
  • 單次實測很吵:重複 local configuration 時,典型最大值÷最小值為 1.51×,最寬到 5.41×。單憑一次 20% 差異,無法與這份研究觀察到的 run-to-run variation 區分。

研究最大的限制仍是只有一種 software task,而且 GitHub 已有成熟的 gh CLI;主矩陣的 hosted cells 多數只跑一次,也沒有正式信賴區間、power analysis 或隨機化 arm 順序。它最有價值的地方,是提醒我們不能只看介面標籤;它還不能替 database、browser、SaaS 或內部 API 做結論。

自己做 MCP vs CLI A/B Test:固定一個六步任務

如果你已讀過 AlphaLab 的 Claude Code Token A/B Test,上一篇教的是「同 repo、同 commit、一次只換一個壓縮工具」;這一篇多加兩個更嚴格的鎖:同一個 Agent harness,以及實際 tool path 必須符合 arm

MCP vs CLI paired A/B Test 流程:固定模型、Harness、任務與 backend,只切換 model surface
Paired run 的核心:共用同一個 broker、operation manifest 與 canonical payload,只讓模型看見的 presentation 不同。

Step 1|先寫完成條件,再寫 prompt

在可丟棄的 fixture repo 放一個真實但範圍小的 bug,要求 Agent:① 重現指定 failing test;② 找到責任實作;③ 用一句話說明 root cause;④ 做最小修補;⑤ 加 regression test;⑥ 執行固定驗證命令並回報 changed files。不要拿 production repo 當實驗場,也不要直接把 patch 送給模型。

驗收器不讀 Agent 的「我完成了」,而是在 run 結束後獨立執行:public_test_exit == 0hidden_test_exit == 0patch_scope_okno_test_weakeningforbidden_route_calls == 0。若任務包含 PR,還要核對本輪開始時間後建立的唯一 PR、預期 head SHA 與 branch;「歷史上有任何 PR」絕對不算完成。

Step 2|凍結 Harness manifest

每次 run 都保存一份 manifest.json,至少包含:model ID/revision、reasoning effort、temperature、system prompt、MCP server commit、CLI 版本、起始 commit、cache policy、max turns、timeout 與預算上限。共享欄位必須完全相同;只有事先登記的 model_surface 與因此必然不同的 model-facing tools 可變,並把兩邊 tool definitions 的原文與 hash 都留存。出現其他差異,這一對就不算 paired run。

Step 3|固定後端,只切換模型表面

A|native MCP:模型看見 read/write/patch/test 等 allowlisted operations 的 typed equivalents 與完整 schema。B|CLI façade:模型只看見 shell 與自製 repoctl。兩邊打到同一個 long-lived broker/session;broker 先依 canonical operation manifest 執行,再產生並 hash canonical result,最後才由兩個 presentation adapter 包裝。除 serialization 與 tool-call syntax 外,payload/error semantics、排序、截斷、limits、timeout 與 connection lifecycle 必須一致。

隔離要放在真正的 security boundary:credential 由 Agent sandbox 外、不同 OS user 或 container 的 broker/sidecar 持有;Agent 只能走 allowlisted IPC,不能讀 broker env/cmdline/config,也沒有直連 backend 的 egress。Native arm 移除 CLI、直接 HTTP/API 與檔案後門;CLI arm 移除 native tools。每個 event 都寫入 requested surface、executed backend path 與 MCP transport。只刪 GH_TOKEN,卻把另一個 PAT 留在 Agent environment,門仍沒鎖。

論文前期 21 個 MCP-connected runs 中,6 個只用 MCP、6 個只走 shell、6 個混用、3 個沒叫工具;論文另註記其中有 4 個繞過兩種指定介面、直接打 Web API,但沒有交代這 4 個與前述分類如何重疊。白話說:prompt 只能請參賽者走左門,sandbox、broker 與 backend audit log 才能證明右門真的鎖上。

Step 4|把每個 request 寫成 JSONL

保存的是Harness 組裝後、真正送進模型的 request,不只是 MCP server 回傳的 tools/list。每輪至少記:pair/arm、model snapshot、system 與 tools 原文及 hash、provider usage、schema/result bytes、cache read/write、tool event、retry、latency;run 結束再加 hidden grader、route violation 與實際成本。只有 hash 不夠稽核,原文也要留在私有 artifact。

{"pair_id":"bug-07-r03",
 "arm":{"model_surface":"native_typed","backend_path":"mcp",
        "mcp_transport":"stdio","discovery":"full"},
 "request_index":4,"input_tokens":18420,"output_tokens":612,
 "cache_read_tokens":12600,"cache_write_tokens":0,
 "schema_count":7,"schema_bytes":9310,"result_bytes":842,
 "tool_event":{"operation":"repo.patch","executed_path":"mcp","retry":0},
 "route_violations":0,"completed":null}

上面只是欄位示意,不是論文資料。MCP 與 CLI 要經過同一個計數 proxy,連 subagent request、CLI --help、stdout/stderr 與 retry 都歸檔;但原始 I/O 另記 bytes,只有實際注入後續 model request 的片段才算 input tokens,provider retry 也以 provider usage/invoice 為準。只讀 parent session usage,會讓會分派子代理的 scaffold 虛假地便宜;wc -c 永遠只能叫 bytes。

Step 5|每次重設 repo,交錯執行兩個 arm

每個 run 從同一 immutable SHA 建 fresh worktree;remote/API 狀態則使用唯一 run_id fixture,或先後驗證 issue/branch/PR reset,grader 必須配對 run_id、created_at 與 head SHA。Cold runs 使用隔離 cache namespace;warm runs 先讓各 arm 以自己的相同 prefix 預熱。若 cache 無法控制,就只報 observed fields,把 state 當 measured covariate。3~5 pairs 只能除錯;正式 N 應由 pilot paired variance、預先定義的 minimum meaningful effect 與 CI width/power 決定。只重跑同一 fixture,CI 只適用該 task 的隨機重複;要泛化就抽樣多個 tasks,並按 task/cluster bootstrap。

for task in frozen_tasks:
  for replicate in range(N):
    for arm in randomized(["native_mcp", "cli_facade"]):
      repo = fresh_worktree(task.base_sha)
      harness = frozen_harness.with_adapter(arm)
      recorder.capture_exact_model_requests = True

      outcome = harness.run(task.prompt, repo)
      route_ok = broker.audit(arm, outcome.tool_events)
      grade = hidden_grader(repo, task)
      save(outcome, route_ok, grade)

這是 framework-agnostic pseudocode:把 with_adapter() 換成你 Agent 的 tool registry;broker.audit() 查 backend 事件,而不是相信 transcript;hidden_grader() 則要在 Agent session 結束後、沒有模型參與的程序裡執行。

Step 6|先看成功率,再算 Token 與錢

  • Completion rate:通過全部 checks 的 runs ÷ attempted runs
  • Tokens per verified completion:全部 attempted-run token usage ÷ verified completions;另報單一 request 最大 input/context tokens。若 provider 把 cache read 視為 input 子集,不要再加總一次。
  • Cost per verified completion:全部 runs 成本 ÷ 完成 runs,把 retry 與 failure 一起算進真正產能。
  • Failure cost share:失敗 runs 成本 ÷ 全部成本
  • Path adherence:主分析按原始 arm 分派保留每次 attempted run;route violation 視為未通過,成本仍留在分母。可另做 adherent-only sensitivity analysis,但不能取代主結果。

兩邊都通過驗收的 pair,才計算 paired surface delta = cost(native MCP) − cost(CLI façade);所有 assigned-arm 失敗與成本仍另報。Route violation 預先定義為 apparatus failure,主表用 intention-to-treat 保留,再加 per-protocol sensitivity。若要找機制,再做 CLI full vs filtered/TOON 與 MCP eager vs progressive discovery;不要把 projection 或 delivery 節省倒灌成「CLI 天生勝出」。

想把觀測補齊,可延伸讀 Agent Observability;想先理解 loop、tools 與 stop condition,先補 AI Agent Harness 心智模型,再看 最小 Harness 實作

MCP vs CLI 怎麼選?其實還有第三條路

MCP vs CLI 與 Lazy MCP 決策表:工具探索、型別、輸出過濾、適用任務與主要成本
決策重點不是站隊:依工具集合大小、使用密度、輸出形狀與風險,選 eager typed、CLI 或 lazy MCP。

選 typed MCP,如果「不猜參數」比省幾行說明更重要

新 API、內部服務、會寫入外部狀態的動作,typed input、可選的 output schema、由 server/host 強制執行的授權與確認政策,以及可發現性很有價值。尤其模型不熟悉自家 CLI 時,明確 schema 可能減少錯參數與 retry。這時要優化的是 tool design:工具窄、描述清楚、結果小,而不是為了省 token 把型別全部拆掉。

選 CLI,如果任務窄、命令成熟,而且輸出很好裁

gitghrgjq 這類成熟工具,模型通常能用短命令完成,而且 shell 可以在結果進 context 前先 filter。已知、重複、可用 deterministic script 驗收的 pipeline,CLI 常是最小可用介面。代價是你要自己管理 quoting、exit code、credential 與 sandbox。

選 lazy/compressed MCP,如果工具很多、每次只會用少數

這條路保留 MCP protocol path、server 原有的授權機制與 typed tools,但只先露出名稱索引或 search_tools,命中後才展開完整 schema;結果再交給 code execution 或本機 filter。這也符合目前的 MCP client progressive-discovery 指引。注意:那份官方頁面的 token 圖是機制示意,不是控制 benchmark。

mcptoon 是好用的「兩軸」示例,但不適合直接充當 surface-only 主 arm。它公開的 97% discovery、40–60% result savings 是作者 microbenchmark,不是 task-level Agent A/B。截至 2026 年 8 月 12 日,PyPI 最新版是 0.2.1;GitHub main 的 pyproject/README/CHANGELOG 已是 0.2.2,source 固定 MCP 2024-11-05。TOON 預設把結構中的 string scalar 截到 200 字元、整體上限 4,000 字元,不能稱為無損;usage token 目前也未由 call path 填入。即使用 --json --full,它仍會抽取/重包內容、套用 guard 並管理自己的連線生命週期,不等於 raw MCP semantics。只有通過 canonical-payload equivalence test 才能當 paired arm;否則另列 bundled-client arm。

若你的重點是 MCP transport 本身如何跨無狀態部署,可接著讀 Stateless MCP 教學;若你想整理「哪些內容應該進 context」,則看 Context Engineering

MCP vs CLI 實驗最常踩的 6 個坑

  1. 連 Harness 一起換:用 A 產品測 MCP、B 產品測 CLI,得到的是產品差,不是介面差;CLI façade 的後端也可能仍走 MCP,務必分開記 surface、backend path 與 MCP transport。
  2. 只在 prompt 指定介面:Agent 有別條路就可能偷走;一定要移除 config、credential 或 network route,再查 tool register。
  3. 相信 final answer:「已完成」不是驗收。用 repository state、測試、API 或資料庫查詢做外部 grader。
  4. 只留下成功 runs:昂貴失敗被刪掉後,最不穩定的 arm 會看起來最省。
  5. 把 cached tokens 當免費:cache 會改變帳單,但 token 仍可能占 context,provider 的折扣規則也不相同;raw input、cached input 與實付成本要分欄。
  6. 只跑一次:Agent 具有隨機性,服務延遲與 cache 也會漂;報 paired repetitions、median、range,再判斷差異是否大到值得改架構。

常見問題(FAQ)

Q1:MCP 天生比 CLI 貴嗎?

不一定。目前公開研究報告的 paired ratios 方向不穩,且其 harness 有路徑與驗收缺口;MCP client 如何載入 schema、任務跑幾輪、結果是否先過濾,都會改變答案。

Q2:那 CLI 一定比較省 Token 嗎?

也不一定。CLI 若讓 Agent 一直查 --help、猜參數、重試,或把巨大 JSON 原樣回填,可能比一個窄而清楚的 typed tool 更貴。

Q3:單一 MCP server 真的會占 40K context tokens?

某些組合可能,但 40K 不是協定常數。那個數字來自一位實作者對 186 tools、約 168 kB JSON Schema 的自述估算;server 大小、client 呈現方式與 tokenizer 改變,結果就會變。

Q4:MCP 規格要求 client 把全部 schema 放進每個 request 嗎?

不是這樣規定。規格定義 tools/listtools/call 與 tool schema,也允許 client 自行決定互動呈現;2026-07-28 版還明列 listing 的 pagination 與 caching。

Q5:Prompt cache 會把 Harness Tax 全部消掉嗎?

不會。它可能降低重複前綴的計費,但結果、未命中的 prefix、重試與 context 容量仍存在。實驗要同時保存 raw input、cached input 與實付成本。

Q6:怎麼確認 Agent 沒有偷換工具?

用兩層證據。第一層讓 Agent process 根本拿不到另一條路的 credential/config/network access;第二層由 backend 記錄每個 tool、shell command 與 outbound request。只看 prompt 或 transcript 不夠。

Q7:最該盯的單一指標是什麼?

Cost per verified completion。它把「有沒有真的完成」放回分母,也不會讓失敗與 retry 消失;再配 failure cost share,才能看出尾端風險。

Q8:什麼時候值得改成 lazy/compressed MCP?

工具很多、實際使用稀疏、schema 或結果已成為可觀測瓶頸時。先從 log 證明 fixed schema bytes 與 result bytes 確實占大頭,再改 discovery;不要只因網路上一個百分比就重寫整套 client。

給新手的 5 個重點

  • MCP vs CLI 是介面比較;Harness Tax 才是完整成本問題。
  • 同模型還不夠,system prompt、built-in tools、cache、starting state 與 stop rule 都要固定。
  • 先用外部 grader 驗收,再比較 tokens、cost、retries。
  • 隔離實際路徑並記錄 tool register,否則你量到的是未知混合物。
  • typed MCP、CLI 與 lazy MCP 可以共存;依任務選最小但足夠可靠的介面。

想把這套方法放進自己的 Agent 專案,可以從 AlphaLab AI 課程補齊 prompt、tools、eval 與 automation 的實作脈絡;也可回到 AI 專區,依序讀完 Harness、Context Engineering 與 Observability。

接著閱讀

左右滑動查看更多推薦

結語:先秤背包,再爭哪條路比較短

「MCP 還是 CLI?」像在問兩條路哪條省油,卻沒先看車重、塞了多少貨、繞了幾圈、失敗後重跑幾次。真正可攜的答案不是固定倍數,而是分清兩本帳:Context 負載包含固定前綴、動態 schema/result/transcript 與重跑流量;帳單再依 provider 對 uncached input、cache read/write、output/reasoning 的費率計算

今天就選一個可重設的測試 repo,寫下五個 machine checks,保存 system/tool schema 原文與 hash,跑第一對隔離的 native MCP/CLI façade sessions。只要你能證明「兩邊真的做了同一件事、真的走了指定路、真的完成」,下一個 token 數字才值得相信。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週一封,第一時間收到新文章與投資觀察。

我們不會 spam,隨時可退訂。