[TOOLS] 13 分鐘閱讀OraCore 編輯部

mcp-use 讓任意 LLM 接上 MCP

我拆 mcp-use 的 MCP agent 流程,整理成可直接複製的模板,讓你把任意 LLM 接到任意 MCP server。

分享 LinkedIn
mcp-use 讓任意 LLM 接上 MCP

這篇直接拆 mcp-use 的 agent 流程,最後給你一份可複製的模板,把任意 LLM 接到任意 MCP server。

我最近一直在玩 MCP,玩到有點煩。不是 MCP 不行,是很多人把它做得像展示品:server 有了、client 有了、demo 也能跑,然後一碰到真實工作流就開始卡。模型綁死、工具綁死、wrapper 綁死,最後你不是在做 agent,你是在維護一坨很會聊天的黏土。

我看到 mcp-use 時就停了一下。不是因為它多炫,而是它把我最在意的那件事講得很直白:把任意 LLM 接到任意 MCP server,讓 agent 的工具層保持在你手上。這種東西才有實戰味,不然一切都只是 demo。

我今天想拆的不是「這專案有多厲害」,而是它背後那套方法論:模型跟工具要分開、設定要顯性、agent loop 要可控,還有你到底該怎麼把這套東西抄進自己的專案裡。這才是有用的部分。

這篇的觸發來源就是 mcp-use GitHub repo 跟它的 README。README 沒有給我什麼神話故事,它就是老老實實講它是個 fullstack framework,用來做 MCP apps、servers 跟 custom agents。

先把模型跟工具拆開,不要再混成一鍋

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

mcp-use 是一個開源 library,讓開發者可以把任意 LLM 接到任意 MCP server,做出有工具能力的 custom agents,而且不用綁死 closed-source 或 app-specific client。

翻譯一下就是:模型是模型,工具是工具,兩者不要硬黏在一起。這句話聽起來很廢,但我真的看過太多專案一開始就把兩者混成一個黑盒,然後後面每改一次需求都在拆炸彈。

mcp-use 讓任意 LLM 接上 MCP

mcp-use 的思路是先把工具面定義成 MCP server,再讓 LLM 透過 agent 去選工具、呼叫工具、讀工具結果。也就是說,模型不是主角,模型只是決策器;真正的能力在工具層。這個心法很重要,因為你一旦把模型當主角,後面就很容易開始迷信 prompt,忘了系統設計。

我以前做過一個內部助理,前期大家都很開心,因為它會講話、會總結、會裝懂。結果一旦要接內部 API、文件搜尋、瀏覽器自動化,整個架構就開始歪。原因很簡單:我先選了模型,再硬塞工具。那不是 agent,那是把聊天窗硬改成工作台,當然會痛。

實操上我會先倒過來做:先列工具,再選模型。這個 agent 要查什麼?要讀檔嗎?要跑瀏覽器嗎?要打內部服務嗎?工具邊界先定好,模型只是接在上面的思考層。這樣你才有辦法換模型,不會每換一次供應商就重寫一輪。

  • 先定任務邊界,再選模型,不要反過來。
  • 工具能力盡量收進 MCP server,不要散在 app 裡的私房小抄。
  • 把 agent 做成可替換的薄層,模型才有機會隨時換。

設定要攤開來寫,不要藏在 UI 後面

我喜歡 mcp-use 的另一個點,是它把設定寫得很白。README 裡的範例是用 MCP client config 明確定義 server,包含 command、args 跟 env。這種東西看起來一點都不性感,但我就是偏愛這種沒廢話的寫法。

白話講,這代表工具來源是可讀的、可查的、可版本控制的。不是你點了某個 UI 才知道它底下接了什麼,也不是某個神秘 wrapper 幫你偷接本機環境。這件事很重要,因為 AI 專案最常死在「大家都以為有記錄,但其實沒有」。

client = MCPClient(config = {
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"],
      "env": { "DISPLAY": ":1" }
    }
  }
})

我以前踩過一個坑:demo 在我電腦上跑得超順,換到同事機器就開始抽風。後來才發現它其實偷偷依賴某個 browser session 跟某個本機狀態。這種東西最煩,因為你不是在 debug 功能,你是在找幽靈。

實操上我會把 MCP server 設定放進版本控制,當成部署設定來管,不是當成「先跑起來再說」的臨時檔。你如果一個 team 兩個人以上,這件事就更不能省。設定不顯性,最後一定會有人說「我本機可以啊」,然後大家一起浪費下午。

這裡我也會順手把 Model Context Protocol 當成契約本身來看。mcp-use 只是 adapter 層,真正的接口是 MCP。你把這個層次看清楚,後面就不會把 library 當成宇宙中心。

別被單一 client 綁住,模型要能換

README 裡提到 mcp-use 相容於任何 LangChain 支援的 LLM provider。這句看起來像相容性說明,實際上是整個架構能不能活下來的差別。

mcp-use 讓任意 LLM 接上 MCP

翻譯一下就是:今天你可以用 OpenAI,明天換 Anthropic,後天換別的 provider,agent 的工具層不用整個重寫。模型變成可替換零件,不是綁約。這很重要,因為你在做 agent 時,往往不是在找「唯一最強模型」,而是在不同模型之間找平衡:規劃能力、工具遵循、成本、延遲,全部都要算。

我自己很常遇到這種情況:某個模型規劃比較穩,另一個模型對工具輸出比較老實,第三個模型便宜到適合拿來先跑 prototype。你如果把 agent 跟單一 provider 綁死,這些比較都會變得很痛苦。每次換模型都像在拆房子,不是在換燈泡。

實作上我會把模型層包在一個明確的 provider abstraction 裡,像 LangChain 這種已經有人整理好的接口。mcp-use 負責工具橋接,LangChain 負責模型接入,兩者各做各的。這樣你測的是 agent 行為,不是一直在改 glue code

  • 模型用來比較行為,不要拿來綁架整個架構。
  • 工具 contract 固定,模型可以隨時換。
  • 評估時看 task-level 成果,不要只看單輪輸出漂不漂亮。

agent loop 才是重點,不是一句 prompt 就結束

README 的範例很短,但它其實把 runtime 形狀講得很清楚:先建 LLM,再建 MCP client,再建 agent,最後用一個 max step limit 去跑任務。這不是聊天機器人那種一次性輸出,這是迭代式工作流。

也就是說,agent 會看工具、選工具、呼叫工具、讀回傳、再決定下一步,直到完成任務或撞到步數上限。這差很多。前者是你問一句它回一句;後者是它真的在做事。當你要它碰真實流程時,這種差異就很要命。

我現在看 agent 專案,第一個會盯的就是 step limit。沒上限,agent 很容易開始繞圈;有上限,至少它會在失控前停下來。三十步不是神奇數字,但它透露出一個態度:這東西預設就是多輪推理,不是單次問答。

實操上我會先設保守的 step cap,再看任務是不是需要更多空間。然後我一定會 log 每次 tool call。因為你 debug agent 的時候,最想知道的不是它「有沒有很聰明」,而是它到底是哪一步選錯工具、哪一步讀錯結果、還是哪一步根本跑太久。

README 裡的餐廳搜尋例子很簡單,但模式可以直接換皮:內部文件搜尋、瀏覽器研究、資料清理、報表整理,控制流都一樣。這就是我喜歡這種架構的原因,任務會變,loop 不用變。

動態選 server 才像真的在 orchestrate

mcp-use 提到的一個功能是 dynamic server selection,意思是 agent 可以根據任務挑最適合的 MCP server。這個我真的有感,因為一旦你開始有兩個以上工具域,固定綁死就會變得很笨。

白話講,不是每個動作都丟同一個工具箱。你有 browser server、file server、internal API server,agent 可以根據 prompt 跟上下文去選。這件事的價值不在「很酷」,而在「不會把 prompt 寫成垃圾場」。

我之前做過一個同時要查網頁跟查內部文件的 agent。只要我硬把兩者塞進同一個 tool surface,prompt 就開始膨脹,輸出也開始亂。問題不是工具太少,是工具邊界太爛。動態選 server 至少讓 agent 有選擇,但不是放任它亂來。

實操上我會把工具按工作類型切開,不按功能炫不炫切。瀏覽器一組、檔案一組、內部業務邏輯一組。每個 server 都小一點,測試也容易一點。這樣 agent 要路由時,才不會像在雜貨店找螺絲起子。

如果你想要一個簡單的心法,我會把 MCP server 當成窄而清楚的 service,而不是大雜燴工具。越專,agent 越容易選;越專,我也越容易 debug。這個道理很土,但很有用。

fullstack 不是噱頭,是把 demo 拉到可維護的那條線

repo 描述把 mcp-use 說成 fullstack framework,涵蓋 MCP apps for ChatGPT、Claude,還有 MCP servers for AI agents。這句話我覺得值得留意,因為它不是單純的 SDK,還在碰 app 的組裝方式。

翻譯一下就是:它想處理的不只是「怎麼呼叫工具」,還有「怎麼把這個 agent 做成一個別人能用、團隊能維護的東西」。這是很多 agent library 最常漏掉的地方。它們很會 demo,但一碰到 auth、UI、部署、權限切分,就開始裝死。

我喜歡這種 fullstack 角度,不是因為我想把事情做大,而是因為我不想每次都從腳本長出一個半成品。你如果有一條清楚的 app 組裝路徑,prototype 才有機會真的變成可交付的功能,不然最後只剩「我本機跑得動」。

實操上我會把專案拆成三層:第一層是 MCP servers,專心暴露工具;第二層是 agent runtime,專心做決策與呼叫;第三層是 app shell,負責登入、UI、部署、監控。三層分開,你才有辦法換其中一層,不用整個推倒重來。

但我也不會腦衝把所有東西都塞進去。fullstack framework 最可怕的地方,就是很容易讓人以為自己在搭平台。其實很多時候你只是需要一個乾淨的工具邊界跟一條能跑的流程,其他都先別急。

可抄的模板

import asyncio
from langchain_openai import ChatOpenAI
from mcp_use import MCPAgent, MCPClient

# 1) 先把 MCP servers 寫清楚
#    這份 config 直接進版本控制,別藏在 UI 後面
client = MCPClient(config={
    "mcpServers": {
        "browser": {
            "command": "npx",
            "args": ["@playwright/mcp@latest"],
            "env": {"DISPLAY": ":1"}
        },
        "files": {
            "command": "node",
            "args": ["./servers/file-server.js"]
        },
        "internal_api": {
            "command": "node",
            "args": ["./servers/internal-api-server.js"],
            "env": {
                "API_BASE_URL": "https://example.internal",
                "API_TOKEN": "${API_TOKEN}"
            }
        }
    }
})

# 2) 模型獨立選,別跟工具綁死
#    你要換 provider,只改這裡
llm = ChatOpenAI(
    model="gpt-4o",
    api_key="${OPENAI_API_KEY}"
)

# 3) agent loop 要有步數上限
#    先保守,真的需要再加
agent = MCPAgent(
    llm=llm,
    client=client,
    max_steps=20
)

# 4) 任務要寫得夠具體
#    不要丟一句「幫我處理一下」就想下班
async def main():
    result = await agent.run(
        "Research the top three internal docs for onboarding, then summarize them."
    )
    print(result)

if __name__ == "__main__":
    asyncio.run(main())

# 我會死守的幾條規則:
# - 一個 MCP server 對一類工作
# - 模型可以換,tool contract 盡量不動
# - server config 要可讀、可追蹤
# - 每次 tool call 都要 log
# - agent 步數先設上限
# - secrets 不要進 source control

如果是我自己開新專案,我會先把上面這個骨架抄下來,再慢慢換成我自己的 server、模型跟任務。重點不是那個 model 名稱,也不是那個 tool command,而是那個結構:server 放一邊、模型放一邊、agent loop 卡中間。

mcp-use 真正值得偷的,不是某個 API 名字,而是它逼你把工具面講清楚、把模型面保持可替換、把 agent 當成可控流程而不是魔法。這套東西如果你有在做 AI 工作流,真的比空談 agent 智能有用太多。

來源致謝:原始材料來自 https://github.com/mcp-use 與其 README,另外參考了 MCP 官方網站LangChain 文件。上面的拆解與模板是我根據原始內容整理出的衍生版本,不是直接複製 repo 原文。