2025 年初,MCP(Model Context Protocol)可以說是 AI 工程圈最火的詞。各大廠商搶著宣布支援 MCP,Anthropic、OpenAI、Mistral 在不到一週內相繼表態,GitHub、Slack、Google Drive 都推出了官方 MCP server。當時感覺 MCP 是 AI agent 的未來基礎設施。

然而到了 2025 下半年,社群裡的聲音開始轉變——有人說 MCP 大部分都是行銷;有人把所有 MCP 換回 CLI 工具;Anthropic 自己則在 10 月推出了 Skills,進一步分走了 MCP 的使用場景。到了年底,Simon Willison 在年度回顧裡直接說:MCP 可能只是「一年的風潮」

這篇來梳理一下 Skills 和 MCP 的差異,以及未來這兩者的分工會長什麼樣子。


MCP 的問題出在哪?

先說 MCP 的理念是好的——定義一個通用協議,讓任何工具都能接上任何 AI,不用每次重新整合。問題出在實際使用上有幾個痛點:

🔹 token 開銷超出想像

MCP 最大的問題是 token 消耗。GitHub 官方 MCP 一開始要吃掉近 50,000 個 tokens 的上下文,之後改版才降到 23,000。Armin Ronacher(Flask 作者)分享他用的 Sentry MCP 也要佔掉 8,000+ tokens。而等效的 gh CLI 指令呢?上下文開銷是零,因為 LLM 本來就受過訓練,知道怎麼用它。

更深層的問題是 MCP 的「單次操作模式」——每次呼叫都要把中間結果返還給 LLM,每一步都在消耗 context。工具一多、步驟一長,光是中間暫存資料就能把 context 塞爆。

🔹 要架 server、要維護

MCP 需要跑一個 server process(local 或 remote),這不只是安裝成本,MCP server 也常常在 API 改版後壞掉,而且不保證向下相容。相比之下,一個 SKILL.md 幾乎零維護。

🔹 工具一多,發現和管理變困難

當 MCP 工具數量增加,每個工具都需要靠名稱和描述被正確發現,agent 還得遵循各工具不同的 input schema。未經優化的工具回傳大量內容,輕易就能塞爆 agent 的 context。這也催生了 MCP gateway 和 discovery middleware 等中間層方案,但也增加了架構複雜度。

🔹 大部分 MCP 只是把 CLI 包裝起來

Peter Steinberger 說得直白:「依我看,大多數 MCP 都只是行銷部門用來打勾自豪的東西。幾乎所有 MCP 其實都應該只是 CLI。我自己就寫過 5 個 MCP,所以我這樣說有根據。」

這個觀察蠻到位的。很多 MCP 的本質就是把一堆 CLI 指令用 JSON schema 描述一遍,然後讓 LLM 透過工具呼叫的方式執行。這和直接讓 agent 跑 shell 指令相比,多了協議層的開銷,卻沒有帶來對等的收益。


Skills 的邏輯是什麼?

Skills 的核心概念其實很簡單:一個資料夾裡放一個 SKILL.md(加上選配的腳本和資源),告訴 Claude 怎麼完成某類任務。agent 看到任務相關時會自動載入對應的 skill。

和 MCP 相比,Skills 的優勢很明確:

🔹 超輕量的 token 開銷

Skill 被載入前,在上下文裡只佔幾十個 tokens 的摘要。只有真正需要的時候才展開完整內容。MCP 則是在連線時就把所有工具定義塞進上下文。

🔹 不需要發明新工具

Simon Willison 說得很有道理:「LLM 知道如何呼叫 cli-tool --help,這代表你不需要花費大量 token 來描述如何使用它——模型在需要時可以自行推敲。」Skills 讓 Claude 的底層工具(bash、檔案讀寫)發揮最大效用,而不是在上面疊一層協議。

🔹 只是 Markdown,人人能寫

不需要懂 JSON schema、不需要架 server、不需要處理 transport 協議。一個會寫 markdown 的人就能做出一個有用的 skill。如果會寫 Python 或 JavaScript,效果更好。

🔹 跨平台

同一份 SKILL.md 在 Claude Code、Codex CLI、Gemini CLI 都能用,不像 MCP 常常要針對不同 client 做適配。

Armin Ronacher 在 12 月直接說他已經把所有 MCP 都換成 skills 了,理由是 skills 更容易維護,而且 LLM 本來就善於用 bash,加上指引就夠了。

Skills 的已知缺點

不過 Skills 也不是沒有弱點。LlamaIndex 團隊在實際比較後指出了幾個關鍵限制:

🔹 非確定性執行

MCP 是確定性的函數呼叫——輸入固定、輸出固定,agent 只需決定「呼叫哪個工具」。但 Skills 依賴 LLM 解讀自然語言指令,agent 需要自己決定「用哪個 skill、什麼時候用、怎麼用」,其中「怎麼用」完全取決於 LLM 的推理品質,同一份 skill 可能產生不同的執行路徑。

🔹 雙重失敗模式

MCP 的失敗模式相對單純:選錯工具。Skills 則有兩層風險——誤解指令 + 選錯工具,因為自然語言本身就容易被 LLM 誤讀或產生幻覺。

🔹 快速演進的領域不太適合

如果你的工具或 SDK 版本迭代很快,skill 裡的 code examples 和 best practices 需要頻繁手動更新。而 MCP 接文件系統或 API,更新會自動傳播,等於有了 single source of truth 的優勢。


大部分場景,Skills 就夠了

重新想想我們為什麼要用 MCP?通常是因為想讓 agent 能做某件事:查 GitHub issues、搜尋文件、操作瀏覽器、讀資料庫…

但仔細想,這些事情很多 agent 直接跑 CLI 就能做到:

  • 查 GitHub → gh issue listgh pr view
  • 操作瀏覽器 → 寫幾個 Node.js 腳本加一份 README
  • 搜尋文件 → grepripgrep、自訂搜尋腳本
  • 讀資料庫 → psql -c "..." 或者一個查詢腳本

Mario Zechner 有個很好的例子:要讓 agent 控制瀏覽器,Playwright MCP 需要 18,000 tokens 的工具定義,Chrome DevTools MCP 也要 13,700 tokens。他自己寫了四個小 Node.js 腳本(start、navigate、evaluate、screenshot)加一份 225 token 的 README,agent 一樣能完成任務,上下文消耗減少了 98%。

這背後的道理很清楚:LLM 受訓時已經看過大量的 shell、Python、JavaScript 程式碼,它本來就知道怎麼用這些工具。過度封裝成 MCP 反而是多此一舉。

編按: 這個思路和 Armin Ronacher 在另一篇文章 Your MCP Doesn’t Need 30 Tools: It Needs Code 裡的論點呼應——與其暴露 30 個工具,不如讓 agent 直接寫 code。他做的 pexpect-mcp 就是一個單一工具的 MCP,接受 Python code 作為輸入,agent 自己用 introspection 探索可用功能,比 30 個獨立工具靈活多了。

MCP vs Skills 的工作流程對照

thecat88tw 用一個很具體的例子說明兩者差異——假設要同時查詢 context7、deepwiki 和 GitHub 三個來源的 React 文件與 issues:

MCP 的流程:

  1. 啟動時把三支 MCP 的規格全部傳給 LLM → 耗用 context
  2. 呼叫 context7 MCP,結果返還給 LLM → 耗用 context
  3. 呼叫 deepwiki MCP,結果返還給 LLM → 耗用 context
  4. 呼叫 GitHub MCP,結果返還給 LLM → 耗用 context
  5. LLM 整理三份資料,輸出最終報告

Skills 可以設計成這樣來節省 context:

  1. 啟動時只傳輕量目錄(告知有哪些 skills 可用)→ 耗用極少 context
  2. 執行 context7 skill,結果存到硬碟 a.md → 不佔用 context
  3. 執行 deepwiki skill,結果存到硬碟 b.md → 不佔用 context
  4. 執行 GitHub skill,結果存到硬碟 c.md → 不佔用 context
  5. 執行 report.py 從三份 md 抽取所需內容,產出 final.md
  6. 視需要返還給 LLM,或留在硬碟等 LLM 之後用 Read tool 讀取

關鍵優勢: 把硬碟當暫存空間,中間結果不需要每次返還給 LLM,大幅降低 context 消耗。這種設計在 coding agent(如 Claude Code)上特別自然,因為它本來就有 shell 和檔案系統存取能力。

Skills 的終極超能力: LLM 當場寫程式

如果上面這個流程是「事先準備好腳本」,那 Skills 還有一個更強的用法——直接讓 LLM 依需求當場寫程式來組合多支 skills 完成任務。

以剛才的例子,那支 report.js 可以不是你手寫的,而是 LLM 即時生成並執行:

const reports = [
  get_context7('react'),
  get_deepwiki('react'),
  get_github('react'),
]
return generate_report(reports)

這樣 LLM 只需一次呼叫就拿到最終報告,省掉多次往返的時間和 token。本來 vibe coding 就是大量依賴 LLM 寫程式的能力,為什麼不發揮它的長處?

當然 LLM 即時寫的程式有時會出錯。有兩個實務解法:一是讓 agent 開發時盡情試錯,成功一次就把那段程式存下來重複使用;二是在 workflow 加上驗證步驟,確認輸出符合預期才放行,不讓錯誤結果流出去。


那 MCP 還有什麼場景?

說了這麼多 skills 的好,MCP 並沒有死。有幾個場景 MCP 還是有意義的:

1. 需要連接有認證的外部系統

如果 agent 需要頻繁存取某個需要 OAuth 或 API key 認證的外部系統,而且這個系統有完善的 API,MCP 的結構化接口是有價值的。例如連接公司內部的知識庫、專有資料庫、或是需要認證的 SaaS 系統。這些場景下,用一個維護良好的 MCP 比讓 agent 自己串認證流程方便。

這也是目前 Skills 已知無法完全解決的問題——在 claude.ai 這樣的 web 服務上,如何代替用戶完成 Google OAuth 流程並安全保管 token?MCP client 目前有完整的解法(由 client 觸發 OAuth,token 保管在 MCP server 內)。不過 Anthropic 工程師表示這個問題他們正在積極解決中。值得注意的是,如果 agent 跑在本機或 container 環境,這個問題其實不存在,Skills 同樣可以支援 OAuth 流程。

2. 需要有狀態 session 的場景

Armin Ronacher 提到的 pexpect-mcp 就是一個好例子——用來跟 LLDB 做互動式除錯,需要維持 session 狀態。這種有狀態的互動,CLI 其實也很難處理,MCP 提供了比較自然的抽象。

3. 通用工具的標準化

有些工具確實值得做成 MCP,因為它是「通用基礎設施」——Chrome DevTools 控制瀏覽器、IDE 整合、本地資料庫存取等,這些是跨專案都會用到的能力,做成一個設定好就忘記的 MCP 是合理的。Peter Steinberger 自己也承認 Chrome DevTools MCP 提供了真正的價值。

4. 快速演進的領域需要 single source of truth

LlamaIndex 團隊分享了他們的實戰經驗:在開發 LlamaAgents Builder 時,他們同時嘗試了 MCP 和 Skills 兩種方案。原本假設 MCP 負責提供知識庫做規劃,Skills 負責寫程式時的具體指引。結果發現——Documentation MCP 提供的 context 就足以讓 agent 產出正確的程式碼,Skills 很少被觸發,即使觸發了也沒有顯著改善結果。

最終他們選擇了 MCP,關鍵原因是 LlamaParse SDK 和 LlamaIndex 本身持續在更新,如果用 Skills 就要不斷手動更新 markdown 裡的範例程式碼。而 MCP 接的是文件系統,文件一更新,agent 拿到的 context 就自動是最新的。

這個案例說明:當你的領域知識變動頻繁,MCP 的集中式更新優勢是 Skills 很難比的。

5. 跨廠商工具整合的標準

MCP 最後的護城河可能是作為行業標準——讓不同 AI client 和工具廠商有共同語言。就像 USB 協議一樣,即使你不需要每天想著 USB 協議,它的存在讓生態系更好接。MCP 年底被捐給基金會治理,走的就是這個方向。


小編觀點: Skills 不是萬用解

這篇討論的情境主要是 coding agent——像 Claude Code、Codex CLI 這種開箱就有 shell 存取能力的工具。在這個環境下,Skills + bash 是很自然的組合:skill 是檔案系統上的一包檔案,腳本可以直接執行,中間結果可以存硬碟,一切都很流暢。

但如果是一般 agent 框架(例如自己用 API 搭的 agent、或企業內部的 workflow 系統),情況就不一樣了:

  • 如果要提供 shell 執行能力,需要準備沙箱 container,整個架構複雜度就增加了
  • Skill 的載入(讀檔、注入 prompt)本身有 latency,這在開發者工具或 B2B 場景尚可接受,但放到 B2C 產品就要認真考量了——普通用戶不知道 skill 是什麼,也不需要知道,他們感受到的只是「為什麼慢了一拍」

編按: ihower 在研究 OpenAI API 的 Skills 功能時也提到這個觀察——coding agent 的 skills 和一般 agent 框架的 skills,其實是兩個很不同的東西。對一般 agent 框架來說,「skills」更像是 progressive disclosure 這個設計模式,而不是像 Codex 那樣開箱即用的完整系統。

所以「Skills 取代 MCP」這個論斷,更準確的說法是:在 coding agent 的場景下,Skills 配上 shell 幾乎可以取代大多數 MCP 的用途。至於一般 agent 框架,MCP 作為標準化的工具協議仍有它的定位,而 skill loading 的成本也需要納入考量。


小結: 分工越來越清晰

整理一下這場討論的脈絡:

  • Skills(和 CLI 工具): 大多數日常 agent 任務的首選,輕量、靈活、低維護成本
  • MCP: 退縮到通用/常用工具(瀏覽器、IDE、資料庫),以及真正需要協議標準化的整合場景

值得一提的是,兩者並非零和。現有的 MCP 可以被包進 Skills 來執行,等於讓 Skills 繼承 MCP 的所有功能,同時享受 Skills 的優勢。有人已依此概念做了 mcporter 這個工具,可直接把既有 MCP 轉成 Skills 使用。從這個角度看,Skills 更像是 MCP 的超集——或者說 MCP 2.0。

Skills 本身也已經走向開放標準,官網 agentskills.io 提供完整規格書,OpenAI Codex 也已宣布支援,不再只是 Claude 的專屬機制。

Simon Willison 說得很準:「如果你的 agent 可以執行任意 shell 指令,它就能做任何可以透過在終端機輸入指令完成的事。」這句話從根本上動搖了大多數 MCP 的存在理由。

所以與其問「要不要用 MCP」,更好的問題可能是:這件事 agent 直接跑 CLI 或寫個腳本就能做到嗎? 如果可以,先從那裡開始——簡單的方案往往就是最好的方案。


參考資料