1. MCP 是什么
全稱:Model Context Protocol
定位:讓大語言模型(LLM)能在“上下文”之外,按統一格式訪問外部數據、調用插件、持久化狀態。
動機:以前每家框架(LangChain、LlamaIndex 等)都有自己的“工具調用/記憶”規范,很難互通;MCP 就是做一個“HTTP/JSON-RPC”風格的公共協議。
2. 結構 & 概念
MCP 定義了幾類對象/消息:
名稱 | 作用 |
---|---|
resources | 模型可直接訪問的數據(文件、數據庫、API、消息流) |
prompts | 可復用的 prompt 模板,外部系統可以動態注入 |
tools | 可調用的外部函數或 API,帶參數 schema |
sessions | 一次上下文交互(可包含用戶消息、模型回復、工具調用) |
capabilities | 服務端聲明自己支持哪些功能(資源、工具、訂閱、推送等) |
協議本質是 JSON-RPC 2.0 風格(雙向流),模型和外部“上下文服務器”之間通過 WebSocket 或 HTTP(SSE/gRPC)傳遞消息。
3. 消息交互流程
角色與數據流(逐步)
用戶 → MCP客戶端
用戶的輸入(語音、文字等)先進到你自己寫的“前端/適配層”,這個層里包含 MCP 客戶端。
MCP 客戶端在收到用戶輸入前,已經向 MCP 服務器拿過一遍
tools/resources/prompts
列表,存著最新的能力元數據。
MCP客戶端 → LLM
MCP 客戶端把用戶輸入 + 工具/資源描述(以及任何 session 上下文)拼成一份上下文,一起發給 LLM。
對于支持 function-calling 的模型,這一步就是把
functions
參數傳進去;對于不支持的模型,就把工具描述寫在 system prompt 里。
LLM 推理
如果它覺得自己能直接回答,就直接返回自然語言。
如果它覺得需要外部數據/工具,就按你提供的工具描述生成一條 工具調用請求(
tool_call
或 JSON)。
LLM → MCP客戶端
這個“工具調用消息”不會直接給用戶,模型返回給 MCP 客戶端。
MCP客戶端 → MCP服務器
MCP 客戶端檢查工具名和參數是否合法,然后調用 MCP 服務器的
tools/call
或resources/read
等 API。
MCP服務器 執行
調后端 API、查數據庫、讀文件,返回 JSON 結果。
MCP客戶端 → LLM(tool_result)
MCP 客戶端把結果包成 “tool_result” 消息再發回給 LLM,讓模型繼續推理生成自然語言。
LLM → MCP客戶端 → 用戶
LLM 生成最終的對話文本。
MCP 客戶端把這個文本轉發回給用戶界面/設備。
sequenceDiagramparticipant User as 用戶participant MCPClient as MCP客戶端(含前端)participant LLM as AI(LLM)participant MCPServer as MCP服務器User->>MCPClient: 用戶輸入MCPClient->>LLM: 用戶輸入 + 工具/資源描述LLM-->>MCPClient: ①直接回答 或 ②tool_call JSONalt 直接回答MCPClient->>User: 轉發 LLM 的自然語言回答else tool_callMCPClient->>MCPServer: 調用工具/資源MCPServer-->>MCPClient: 工具結果MCPClient->>LLM: tool_resultLLM-->>MCPClient: 最終自然語言回答MCPClient->>User: 轉發回答end
關鍵點(回答你的問題)
最后一句話(自然語言回答)總是由 LLM 生成的,因為只有模型能把外部數據變成人能讀懂的話。
真正“發回用戶”的動作通常由 MCP 客戶端來做,因為客戶端是“會話的中間人”,它既能調模型、又能調 MCP 服務器、又能跟你的前端交互。
也就是說:
生成者:LLM
發送者:MCP 客戶端(它把 LLM 的回答發給用戶)
5. 協議格式(簡例)
列出工具
{"jsonrpc": "2.0","id": "1","method": "tools/list"
}
響應
{"jsonrpc": "2.0","id": "1","result": {"tools": [{"name": "search_contacts","description": "Search contacts by name","input_schema": {"type": "object","properties": {"query": {"type": "string"}},"required": ["query"]}}]}
}
調用工具
{"jsonrpc": "2.0","id": "2","method": "tools/call","params": {"name": "search_contacts","arguments": {"query": "Alice"}}
}
6. 應用場景
統一模型插件生態(比如 OpenAI Assistant、Claude Workbench、LangChain agent 都能用同一協議)。
本地/企業內部數據(CRM、ERP、數據庫、知識庫)接入模型。
安全地持久化模型“記憶”。
7.MCP 的標準工作方式
角色 | 作用 |
---|---|
AI(LLM) | 只做推理:理解用戶話 → 生成自然語言或工具調用請求(JSON)。它本身不知道“天氣 API 在哪”。 |
MCP 客戶端 | 嵌在 AI 運行環境里的適配層。負責:- 向 MCP Server 拉取工具列表、資源列表- 把 LLM 生成的“工具調用 JSON”包裝成協議請求發出去- 把響應結果再送回給 LLM。 |
MCP 服務器 | 工具/資源的實際托管地,負責執行真正的 API/數據庫操作,并按 MCP 協議返回結果。 |
時序(以查天氣為例)
sequenceDiagram
participant User as 用戶
participant AI as LLM
participant MCPClient as MCP客戶端
participant MCPServer as MCP服務器? ? User->>AI: “幫我查一下北京的天氣”
Note right of AI: LLM推理<br>發現自己不能回答
AI->>MCPClient: 生成工具調用JSON {name:"get_weather",args:{"city":"北京"}}
MCPClient->>MCPServer: tools/call(get_weather,{"city":"北京"})
MCPServer-->>MCPClient: {"result":"晴 28℃"}
MCPClient-->>AI: 返回工具結果
AI->>User: “北京今天晴,28℃”
LLM 的“工具調用消息”是什么樣子
在 MCP/Assistants 框架里,模型輸出的其實是一個 結構化消息,類似這樣:
{"type": "tool_call","name": "get_weather","arguments": {"city": "北京"}
}
這個消息不會直接給用戶,而是交給 MCP 客戶端去執行。
然后客戶端執行工具 → 把結果打包成一條 “tool_result” 消息送回模型;模型再在上下文里用這個結果生成給用戶的自然語言回復。
MCP調用流程可以簡化為一句話:
LLM 只“決定要不要用哪個工具 + 怎么調用”,真正執行工具和返回結果都是 MCP 客戶端+服務器干的
流程是這樣的 llm可以請求的除了工具 還可以請求資源、提示詞等其他東西
所以標準交互模式:
LLM → MCP客戶端:
list_tools
/list_resources
/list_prompts
…MCP客戶端 → MCP服務器:按 JSON-RPC 發請求
MCP服務器 → MCP客戶端:返回可用項列表
LLM 決定用哪個 → 發起具體調用
MCP服務器執行 → 把結果返回給 LLM
總的來說,MCP 給模型開放了“資源/提示詞/工具/上下文”等一整套統一接口,模型并不需要知道背后是數據庫、API 還是文件,只管按 MCP 協議去“列/讀/調”。用戶只看見 MCP 客戶端,模型負責生成回答或工具調用,客戶端負責把所有東西串起來并最終把模型回答送回用戶。