MCP 協議原理與系統架構詳解—從 Server 配置到 Client 應用

1. MCP

MCPModel Context Protocol,模型上下文協議)是開發 Claude 模型的(Anthropic)公司推出的一個開放標準協議,就像是一個 “通用插頭” 或者 “USB 接口”,制定了統一的規范,不管是連接數據庫、第三方 API,還是本地文件等各種外部資源,目的就是為了解決 AI 模型與外部數據源、工具交互的難題。

在這里插入圖片描述
MCP(Model Context Protocol)的工作機制大致如下:MCP Host(如 Claude Desktop、Cursor 等應用)在其內部集成了 MCP Client。該客戶端通過標準的 MCP 協議與 MCP Server 進行通信。MCP Server 通常由第三方開發者提供,負責實現與外部資源(如數據庫、瀏覽器、本地文件系統等)交互的具體邏輯。執行結果通過相同的 MCP 協議返回至 MCP Client,最終在 MCP Host 界面中呈現給用戶。

在這里插入圖片描述

2. MCP Server 配置結構解析

Cherry Studio 為例,解析 MCP Server 配置為何這樣設計

2.1 通信協議

兩種類型:STDIOSSE

在這里插入圖片描述
MCP 協議中的 STDIOSSE 其實就是是兩種不同的(MCP Server 與 MCP Client)通信模式:

  • STDIO(標準輸入輸出,像面對面對話):客戶端和服務器通過本地進程的標準輸入和標準輸出直接通信。例如:本地開發時,你的代碼腳本通過命令行啟動,直接與 MCP 服務器交換數據,無需網絡連接。
  • SSE(服務器推送事件,像電話熱線):客戶端通過 HTTP 協議連接到遠程服務器,服務器可以主動推送數據(如實時消息)。例如:AI 助手通過網頁請求調用遠程天氣 API,服務器持續推送最新的天氣信息。

通俗地說,STDIO 方式需要將 MCP Server 下載到本地運行并調用,而 SSE 方式則是通過 HTTP 服務遠程訪問托管在服務器上的 MCP Server

SSE MCP Server 的配置示例,直接使用網絡協議和工具進行通信:

{"mcpServers": {"browser-use-mcp-server": {"url": "http://localhost:8000/sse"}}
}

FileSystem、Mongodb 典型的 STDIO 調用:

{"mcpServers": {"mongodb": {"command": "npx","args": ["-y","@modelcontextprotocol/server-filesystem","~/Downloads"]}}
}

STDIO 為程序的輸入輸出提供了一種統一的標準方式,無論是什么類型的程序,只要遵循 STDIO 協議,就可以方便地進行數據的輸入和輸出,并且可以很容易地與其他程序或系統組件進行交互。

在命令行中,使用 STDIO 通信是非常常見的,在 Linux 系統中的 cat 命令就是一個極為簡單且能體現 STDIO 通信的例子。cat 命令通常用于連接文件并打印到標準輸出。當你不指定任何文件時,它會從標準輸入讀取內容,并將其輸出到標準輸出。?在這個過程中,cat 命令從標準輸入讀取內容,接著將輸出重定向到文件,這就是一個最簡單的 STDIO 通信案例。

2.2 命令和參數

對應 JSON 配置中的 command 參數,在沒有填寫時,這里默認推薦的是 uvxnpx

在這里插入圖片描述
mongodb 的例子中, command 使用的就是 npx 。在一些文章中說,只要安裝了 Node.js 環境,就可以使用,那為什么這里不寫 node,而要用 npx 命令呢?

npxNode.js 生態系統中的一個命令行工具,它本質上是 npm的一個擴展npx 的名字可以理解為“運行一個包”(npm execute package)的縮寫

npmNode.js 的包管理工具。通過將通用工具封裝為 npm 包發布,任何安裝了 Node.js 的環境都能輕松下載并使用這些功能。

npx 的主要功能就是幫助快速運行一些通過 npm 安裝的工具,而不需要手動去下載安裝這些工具到全局環境。

{"mcpServers": {"mongodb": {"command": "npx","args": ["-y","@modelcontextprotocol/server-filesystem","~/Downloads"]}}
}

在這個配置中,args 里第一個參數 "-y" 其實就等同于 --yes,其作用是在執行命令時自動同意所有提示信息,可以避免交互式的確認步驟。

第二個參數其實就是這個 npm 包的名字,比如 @modelcontextprotocol/server-filesystem 這個包:

在這里插入圖片描述
args 里的第三個參數就是傳遞給這個包的一個必備參數:允許讀取的本機路徑。

這幾個信息,再加上大模型分析用戶輸入后得出的參數,通過 STDIO 協議傳遞給這個包,就可以構成一條在終端直接可以運行的一條命令:

npx -y @modelcontextprotocol/server-filesystem ~/Downloads  <<< '{"method":"tools/call","params":{"name":"list_directory","arguments":{"path":"~/Downloads"}},"jsonrpc":"2.0","id":1}'

把輸入內容格式化:
在這里插入圖片描述

<<<(Here 字符串操作符)的主要用途是將一個字符串作為標準輸入(STDIN)傳遞給前面的命令。

在這個命令中,通過 <<< 操作符,把后面的字符串傳遞給前面的命令(也就是@modelcontextprotocol/server-filesystem 這個包)當作輸入數據。?后面的字符串中包含了需要調用的函數(list_directory),以及傳遞給這個函數的參數(~/Downloads),前面的部分都是在 MCP Server 中配置的內容,屬于固定的部分。而大模型做的,就是根據用戶當前的輸入,以及當前支持的 MCP 工具列表,判斷出要不要調用這個工具,如果要調用,生成結構化的工具參數,最后 MCP Client 通過 STDIO 協議將這個結構化的參數再傳遞給 MCP Server

在上面的命令中,還有一個選項是 uvx,和 npx 類似,它也可以直接讓你臨時執行某個工具包,而無需全局安裝。不過 uvx:是 uv 工具鏈的一部分,主要聚焦于 Python 生態系統,它會創建一個臨時的隔離 Python 環境來運行 Python 工具包。

在這里插入圖片描述

2.3 傳輸格式

請查看剛才命令的執行結果。
在這里插入圖片描述
也是一段格式化好的內容,里面返回了當前目錄下的所有文件,而模型在接收到這段格式化的輸出后,會將其變成口語化的內容再返回到 MCP 客戶端。

這個輸入、輸出的參數格式,遵循的是 JSON-RPC 2.0 傳輸格式,它有一套自己的規則,規定了請求和響應的格式、如何處理錯誤等,官方文檔的中的描述:

在這里插入圖片描述

2.4 Windows 配置

實際使用時,您可能會注意到該配置在Windows系統中可能無法正常生效。

{"mcpServers": {"mongodb": {"command": "npx","args": ["-y","@modelcontextprotocol/server-filesystem","~/Downloads"]}}
}

需要改成下面的方式:

{"mcpServers": {"mongodb": {"command": "cmd","args": ["/c","npx","-y","@modelcontextprotocol/server-filesystem","~/Downloads"]}}
}

這是因為在不同操作系統下 默認命令解釋器(Shell)的工作機制不同:

  • macOS 的終端(如 bash/zsh)是 Unix shell,支持直接執行可執行文件(如 npx)。
  • Windows 的默認命令解釋器是 cmd.exe,而非直接執行程序。即使 npx 已安裝(如通過全局 npm install -g npx),也需要通過 cmd.exe 來調用,因為:
    • Windows 不直接識別 Unix 風格的命令路徑(如 npx 本質是 Node.js 腳本,需通過 node 執行)。
    • cmd.exe 需要明確的指令格式(如 /c 參數用于執行命令后退出)。

args 中的 /ccmd.exe 的參數,表示“執行后續命令后關閉窗口”。完整的執行流程是:

cmd.exe /c npx -y @modelcontextprotocol/server-filesystem "~/Downloads"

這里 cmd.exe 先解析 /c,再將 npx … 作為子命令執行,確保 Windows 能正確調用 Node.js 腳本(npx)。

通過分析 MCP Server 的配置,了解了 MCP ClinetMCP Server 的通信協議、執行的命令和參數,以及兩者數據傳輸的標準格式,這樣 MCP ClinetMCP Server 的交互方式基本上就弄清楚了。

那執行 MCP Server 一定要通過 npx 或 uvx 運行一個包嗎?

當然不是,實際上任何能夠在命令行執行代碼的方式,都是可以的,比如可以直接把一個 MCP Server 的倉庫拉取到本地,然后通過 nodepython 命令直接執行里面的代碼文件,這樣就可以實現完全斷網運行(前提是 MCP Server 中不會調用遠程 API)。

{"mcpServers": {"mongodb": {"command": "node","args": ["/path/mcp-server.js"]}}
}

3. MCP Server 開發與調試

3.1 基于 AI 輔助編寫 MCP Server

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";const server = new McpServer({name: "TimeServer",     // 服務器名稱version: "1.0.0",       // 服務器版本
});// 注冊工具:獲取當前時間
server.tool("getCurrentTime", // 工具名稱"根據時區(可選)獲取當前時間", // 工具描述{timezone: z.string().optional().describe("時區,例如 'Asia/Shanghai', 'America/New_York' 等(如不提供,則使用系統默認時區)"),},async ({ timezone }) => {try {const now = new Date();let timeString: string;if (timezone && Intl.supportedValuesOf("timeZone").includes(timezone)) {timeString = now.toLocaleString("zh-CN", {timeZone: timezone,timeZoneName: "short",});} else {timeString = now.toLocaleString("zh-CN");}return {result: {currentTime: now.toISOString(),formattedTime: timeString,timezone: timezone || Intl.DateTimeFormat().resolvedOptions().timeZone,},};} catch (err) {return {error: {message: `獲取時間失敗: ${err instanceof Error ? err.message : String(err)}`,code: "TIME_ERROR",},};}}
);/*** 啟動服務器,通過 STDIO 與 MCP Host 通信*/
async function startServer() {try {console.log("正在啟動 MCP 時間服務器...");const transport = new StdioServerTransport();await server.connect(transport);console.log("MCP 時間服務器已啟動,等待請求...");} catch (error) {console.error("啟動服務器時出錯:", error);process.exit(1);}
}// 啟動服務
startServer();
  • 第一步:使用官方提供的 @modelcontextprotocol/sdk/server/mcp.js 包,創建一個 McpServer 實例:

    // ==================== 第一步:創建 McpServer 實例 ====================
    import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
    import { z } from "zod";// 創建 MCP 服務器實例,聲明服務名稱和版本
    const server = new McpServer({name: "TimeServer",     // 服務名稱,用于標識version: "1.0.0",       // 版本號,便于管理更新
    });
    
  • 第二步:使用 server.tool 定義提供的工具方法,包括工具方法的名稱、工具方法的描述、工具方法的參數、工具方法的具體實現邏輯。?另外使用了 "zod" 這個包定義了方法參數的類型以及描述。

    // ==================== 第二步:注冊工具方法 ====================
    // 定義一個可被 LLM 調用的工具:獲取當前時間
    server.tool("getCurrentTime", // 工具名稱"根據時區(可選)獲取當前時間", // 工具描述{// 使用 zod 定義參數結構和校驗規則timezone: z.string().optional().describe("時區,例如 'Asia/Shanghai', 'America/New_York'(不填則使用系統默認時區)"),},async ({ timezone }) => {try {const now = new Date();let formattedTime: string;// 如果提供了合法時區,則格式化為對應時區時間if (timezone && Intl.supportedValuesOf("timeZone").includes(timezone)) {formattedTime = now.toLocaleString("zh-CN", {timeZone: timezone,timeZoneName: "short",});} else {// 否則使用本地時區formattedTime = now.toLocaleString("zh-CN");}// 返回標準格式的結果return {result: {currentTime: now.toISOString(),formattedTime,timezone: timezone || Intl.DateTimeFormat().resolvedOptions().timeZone,},};} catch (err) {// 返回標準錯誤格式,避免拋出異常導致進程退出return {error: {message: `獲取時間失敗: ${err instanceof Error ? err.message : String(err)}`,code: "TIME_ERROR",},};}}
    )
    
  • 第三步:啟動 Server,并且使用 SDK 中導出的 StdioServerTransport 來定義工具使用 STDIO 通信協議,等待外部的標準輸入,并且把工具的執行結果轉化為標準輸出反饋到外部。

    ==================== 第三步:啟動服務器,使用 STDIO 通信 ====================
    async function startServer() {try {console.log("正在啟動 MCP 時間服務器...");//// 建基于標準輸入/輸出的傳輸層const transport = new StdioServerTransport();// 將服務器連接到 STDIO 傳輸,開始監聽 stdin 并向 stdout 輸出響應await server.connect(transport);console.log("MCP 時間服務器已啟動,等待來自 Host 的請求...");} catch (error) {console.error("啟動服務器失敗:", error);process.exit(1); // 啟動失敗時退出進程}
    }// 執行啟動函數
    startServer();
    

操作非常簡單,只需按照這個模板添加更多工具功能即可。ResourcesPrompt的編寫方法也基本一致,大家只要根據提示詞模板定義好需求,AI(特別是Claude的準確度最高)通常都能很好地完成任務。

3.2 使用 inspector 調試 MCP Server

開發完成后,可以直接使用官方提供的 MCP Server 調試工具(@modelcontextprotocol/inspector)來進行調試。也可以直接通過 npx 運行 @modelcontextprotocol/inspector

npx @modelcontextprotocol/inspector <command> <arg1> <arg2>

調試剛剛開發好的工具,這里直接使用 node 運行本地構建好的代碼:

npx @modelcontextprotocol/inspector node dist/index.js

在這里插入圖片描述
在這里插入圖片描述
連接成功后,點擊 List Tools

在這里插入圖片描述
然后可以看到當前 MCP Server 定義的所有工具,這里定義了一個獲取當前時間的工具,點擊這個工具,可以對它進行調試:
在這里插入圖片描述
然后可以看到當前 MCP Server 定義的所有工具,這里定義了一個獲取當前時間的工具,點擊這個工具,可以對它進行調試:
在這里插入圖片描述
基于這樣的思路,可以使用 @modelcontextprotocol/inspector 調試任意的 MCP Server, 在你想要使用,但是還不知道怎么使用一個 MCP Server 時,都可以使用它進行調試:

npx @modelcontextprotocol/inspector npx -y @modelcontextprotocol/server-filesystem  ~/Downloads

在這里插入圖片描述

3.3 在 Cline 中測試 MCP Server

下面在 Cline 中配置測試一下剛剛開發好的 MCP Server,這里直接使用 node 執行:
在這里插入圖片描述
測試結果:

在這里插入圖片描述

4. MCP Client 與 Server 的通信機制詳解

帶著疑問,MCP Clinet 是怎么知道 MCP Server 都提供了哪些工具列表的?模型又怎么從這些工具中選擇出合適的工具?在后續的問答中兩者又是如何配合的呢?
下面用抓包工具來分別對 Cherry Studio 、Cline 兩個工具進行抓包,使用剛剛開發好 MCP Server,分析整個交互過程。

4.1 配置抓包工具

使用 Charles 這個工具來抓包。

Cherry Studio 中,僅有一部分模型支持 MCP ,這里選擇阿里云百煉的 qwen-max,實測在 Cherry Studio 中工具調用是非常穩定的:

在這里插入圖片描述
然后在 Charles 中過濾一下阿里云百煉的請求,就可以過濾出后續的請求包了:

在這里插入圖片描述
Cline 中,所有模型都支持 MCP,這里選擇的是 Openrouter 下免費的 DeepseekV3 。這里需要注意的是, Charles 并不能直接抓取到 VsCode 的請求,需要在 VsCode 下配置代理:

點擊 VsCode 左上角的 “文件” 菜單,選擇 “首選項 > 設置”,搜索 http.proxy,然后在其中填寫 http://127.0.0.1:8888,則可以將 vsCode 后續的請求都代理到 Charles 下:

在這里插入圖片描述
然后在 Charles 中過濾一下 Openrouter 的請求,就可以過濾后續的請求包了:

在這里插入圖片描述
還有一點需要注意,這些軟件一般是都采用的是流式輸出,所以在響應報文里不會展示完整的 JSON 內容,

在這里插入圖片描述
可以借助 AI 幫助還原原始的響應報文

在這里插入圖片描述

4.2 Cherry Studio 抓包分析

Cherry Studio 中開啟剛剛開發的 Time MCP Server,然后詢問 “紐約時間” :

在這里插入圖片描述
發現軟件實際調用了兩次 LLM API

在這里插入圖片描述
下面直接來看我已經處理好的請求報文(省略了一些無關內容,只保留關鍵信息):

  • 第一次請求: 客戶端 將從 MCP Server 獲取到的所有的工具列表,通過 tools 參數傳遞給了模型,相當于告訴模型,我現在有這些工具,你可以根據用戶的輸入(messages.content) 判斷是否使用工具,以及使用哪個工具:
    在這里插入圖片描述
    第一次響應:模型根據用戶輸入的內容,以及當前支持的工具列表,判斷需要使用 getCurrentTime 工具(這里使用 id 進行映射),并且拼接好了工具調用所需要的標準參數格式:{"timezone": "America/New_York"}:
    在這里插入圖片描述
  • 第二次請求:客戶端將上次模型返回的工具調用參數,以及在本地執行工具調用后的結果都合并到 messages 里,傳遞給模型,讓模型基于這些信息生成最終回答:
    在這里插入圖片描述
    第二次響應:模型根據輸入的信息產出最終回答給用戶的內容:
    在這里插入圖片描述

4.3 Cline 抓包分析

Cline 中配置好 Time MCP Server ,并且詢問同樣的問題:

在這里插入圖片描述
然后發現 Charles 中同樣抓到兩條請求:

在這里插入圖片描述
同樣的,把請求報文處理好,并保存到本地查看:

  • 第一次請求:發現請求中并沒有像 Cherry Studio 一樣,包含 tools 字段,而是包含了一段超長的系統提示詞(統計了一下,居然長達 41695 個字符,可見 Cline 真的挺費 Token 的。):
    在這里插入圖片描述
    然后,對這段系統提示詞進行了處理了分析,提取出了關鍵的部分,來具體分析一下:
    提示詞第一部分身份設定
    在這里插入圖片描述
    提示詞第二部分工具使用相關
    • 使用原則:說明工具需用戶批準后執行,每條消息只能用一個工具,依據上次工具使用結果逐步完成任務。
    • 格式規范:給出工具使用的類似 XML 標簽格式示例,如 <read_file><path>src/main.js</path></read_file>
      在這里插入圖片描述
      具體工具介紹:以 use_mcp_tool 為例,詳細說明其描述、參數(必填的 server_nametool_name、arguments)和用法,并給出使用示例。
      在這里插入圖片描述
      使用指南:包括在 <Think> 標簽中評估信息、選擇合適工具、迭代使用工具、按格式使用工具、依據用戶回復結果決策、等待用戶確認等內容。
      在這里插入圖片描述

提示詞第三部分MCP Server 相關

  • 協議作用:介紹模型上下文協議(MCP)允許系統與本地運行的 MCP 服務器通信,擴展能力。?
  • 已連接服務器操作:說明連接服務器后可通過 use_mcp_tool 使用工具、access_mcp_resource 訪問資源。?
  • 可用工具:說明工具的描述、具體參數信息
    在這里插入圖片描述

提示詞第四部分一些約束信息

在這里插入圖片描述
提示詞第五部分目標工作流程

  • 任務分析與目標設定:分析任務設定可實現目標并排序。?
  • 目標處理與工具使用:依次處理目標,每次用一個工具,調用工具前分析并確定參數。?
  • 任務完成與結果展示:完成任務用 attempt_completion 工具展示結果,可提供 CLI 命令,根據反饋改進,避免無意義對話。
    在這里插入圖片描述
    這就是 Cline 系統提示詞的關鍵部分,當前這里省略了一些和 MCP 不相關的信息,比如 Cline 本身提供的一些讀取文件、編寫代碼的工具等等。
    • 第一次響應:這里和 Cherry Studio 也不一樣,并沒有使用 tools_call 字段,而是直接使用 assistant 字段返回需要調用的工具信息 在這里插入圖片描述
      格式化一下,發現和系統提示詞里要求的工具調用格式是相同的
      在這里插入圖片描述
    • 第二次請求:客戶端將上次模型返回的工具調用參數,以及在本地執行工具調用后的結果都合并到 messages 里,傳遞給模型,讓模型基于這些信息生成最終回答
      在這里插入圖片描述
      第二次響應:模型根據輸入的信息產出最終回答給用戶的內容
      在這里插入圖片描述
      這里依然按照系統提示詞中約定的標準格式返回
      在這里插入圖片描述

4.4 MCP 的核心流程總結

Cherry Studio 實際上是通過將 MCP Server 中提供的工具、響應結果,轉換為 Function Call 的標準格式來和模型進行交互。

ClineMCP Server 中提供的工具、響應結果轉換未一套自己約定的輸入、輸出的標準數據格式,通過系統提示詞來聲明這種約定,再和模型進行交互。

這也解釋了,為什么在 Cherry Studio 中只有一部分模型支持 MCP,前提是選擇的模型需要支持 Function Call 的調用,并且在客戶端進行了特殊適配;而 Cline 則使用的是系統提示詞,所以所有模型都支持。

在這里插入圖片描述

初始化與工具列表獲取:

用戶首先對 MCP 客戶端進行初始化操作,隨后 MCP 客戶端向 MCP 服務器 發送請求以獲取可用的工具列表,MCP 服務器將工具列表返回給客戶端。

用戶輸入與提示詞構建:

用戶在客戶端完成初始化后,向 MCP 客戶端輸入具體請求。客戶端將此前獲取的工具列表與用戶輸入內容相結合,共同組成用于詢問 LLM 的提示詞。

工具傳遞方式選擇:

MCP 客戶端通過兩種方式之一將提示詞傳遞給 LLM :

  • 方式1:使用 Function Call(函數調用)直接攜帶工具列表信息;?
  • 方式2:在系統提示詞(System Prompt)中包含工具列表。

LLM判斷與響應:

LLM 接收到提示詞后,返回判斷結果:

  • 無需工具:LLM直接將處理結果通過MCP客戶端回復給用戶;?
  • 需要工具:LLM先向客戶端返回所需工具的參數格式要求。

工具命令生成與執行:

若需要工具,MCP 客戶端根據 LLM 提供的參數格式,以及 MCP Server 配置的命令模板進行拼接,生成完整的可執行命令,并在本地環境(Local_Env)中執行該命令。

結果處理與輸出:

本地環境執行命令后,將結果返回給 MCP 客戶端。客戶端將執行結果提交給 LLM,由 LLM 對技術化的執行結果進行處理,最終以人性化的語言形式輸出給用戶。

5. 基于 mcp-client-nodejs 的 MCP 交互流程

GitHub源碼:https://github.com/ConardLi/mcp-client-nodejs

使用 Node.js 開發了一個基礎版的 MCP Clinet(基于 Function Call 實現)

在這里插入圖片描述

5.1 基于 LLM 構建 MCP Client

提示詞:

## 需求?
我想開發一個 Node.js 版的 MCP Clinet ,下面有一些參考材料,包括 MCP 基礎介紹、MCP 核心架構介紹、MCP Clinet 開發教程,請你根據這些參考材料幫我開發一個 MCP Client,注意增加完善的中文注釋,以及在開發完成后編寫一個完善的中文 Readme 說明文檔。?
?
## MCP 基礎介紹?
粘貼 https://modelcontextprotocol.io/introduction   的內容。?
?
## MCP 核心架構介紹?
粘貼 https://modelcontextprotocol.io/docs/concepts/architecture   的內容。?
?
## MCP Client 開發教程?
粘貼 https://modelcontextprotocol.io/quickstart/client   的內容。?
?
## 注意點?
- 使用 openai 的 SDK 替換 @anthropic-ai/sdk ,這樣可以支持更多的模型,兼容性更好?
- 你不要指定依賴的版本,如果遇到安裝依賴讓我自己來安裝,你只負責編寫代碼

5.2 項目介紹

1. 核心技術優勢:

  • 支持連接任何符合 MCP 標準的服務器?
  • 支持兼容 OpenAI API 格式的 LLM 能力?
  • 自動發現和使用服務器提供的工具?
  • 完善的日志記錄系統,包括 API 請求和工具調用?
  • 交互式命令行界面?
  • 支持工具調用和結果處理

在這里插入圖片描述
2. 安裝和配置:

git clone https://github.com/ConardLi/mcp-client-nodejs.git
cd mcp-client-nodejs

3. 安裝依賴:

npm install
  • 所需依賴項:
    • @modelcontextprotocol/sdk
    • openai
    • dotenv
    • typescript(開發依賴)
    • @types/node(開發依賴)

4. 配置環境變量:

復制示例環境變量文件并設置您的 LLM API 密鑰:

cp .env.example .env

然后編輯 .env 文件,填入您的 LLM API 密鑰、模型提供商 API 地址、以及模型名稱:

OPENAI_API_KEY=your_api_key_here
MODEL_NAME=xxx
BASE_URL=xxx

5. 編譯項目:

npm run build

6. 使用方法:

要啟動 MCP 客戶端,您可以使用以下幾種方式:

  • 直接指定服務器腳本路徑

    node build/index.js <服務器腳本路徑>   # 其中 <服務器腳本路徑> 是指向 MCP 服務器腳本的路徑,可以是 JavaScript (.js) 或 Python (.py) 文件。
    
  • 使用配置文件

    node build/index.js <服務器標識符> <配置文件路徑>
    

    其中 <服務器標識符> 是配置文件中定義的服務器名稱,<配置文件路徑> 是包含服務器定義的 JSON 文件的路徑。

    {"mcpServers": {"time": {"command": "node","args": ["/Users/xxx/mcp/dist/index.js"],"description": "自定義 Node.js MCP服務器"},"mongodb": {"command": "npx","args": ["mcp-mongo-server","mongodb://localhost:27017/studentManagement?authSource=admin"]}},"defaultServer": "mongodb","system": "自定義系統提示詞"
    }
    

7. 使用 npm 包(npx):

您可以直接通過 npx 運行這個包,無需本地克隆和構建:

# 直接連接腳本
$ npx mcp-client-nodejs /path/to/mcp-server.js# 通過配置文件連接
$ npx mcp-client-nodejs mongodb ./mcp-servers.json

注意:需要在當前運行目錄的 .env 配置模型相關信息

5.3 分析 MCP 詳細交互流程

MCP Client 包含一個全面的日志系統,詳細記錄所有關鍵操作和通信。日志文件保存在 logs/ 目錄中,以 JSON 格式存儲,方便查詢和分析。

  • LLM 的請求和響應 - 記錄與 LLM API 的所有通信?
  • 工具調用和結果 - 記錄所有工具調用參數和返回結果?
  • 錯誤信息 - 記錄系統運行期間的任何錯誤

日志文件連統命名為 [index] [log_type] YYYY-MM-DD HH:MM:SS.json,包含序號、日志類型和時間戳,方便按時間順序查看整個會話。

下面使用 mcp-mongo-server 來演示整個流程,首先在項目目錄新建 mcp-servers.json,并填寫下面的配置:

{"mcpServers": {"mongodb": {"command": "npx","args": ["mcp-mongo-server","mongodb://localhost:27017/studentManagement?authSource=admin"]}},"system": "使用中文回復。\n\n當用戶提問中涉及學生、教師、成績、班級、課程等實體時,需要使用 MongoDB MCP 進行數據查詢和操作,表結構說明如下:xxx"
}

然后執行 node build/index.js mongodb ./mcp-servers.json,客戶端成功啟動:

在這里插入圖片描述
逐個來看一下:

  • [0] [GET Tools]:在客戶端初始化時,拉取當前配置的 MCP Server 下提供的所有工具列表
    在這里插入圖片描述
  • [1] [LLM Request] :向大模型發送 用戶問題,并將所有工具列表(包含函數+參數的具體定義)通過 tools 字段傳遞過去
    在這里插入圖片描述
  • [2] [LLM Response] :模型根據用戶輸入 + 支持的參數列表判斷需要使用的工具,并通過 tool_calls 字段返回
    在這里插入圖片描述
  • [3] [Tool Call]:客戶端根據模型返回的函數+參數+MCP 服務器的配置,拼接成一條可執行的命令,執行第一次工具調用:從 teachers 表中檢索姓張的老師的信息:
    在這里插入圖片描述
  • [9] [Tool Call] :客戶端執行工具調用,查詢課程信息
    在這里插入圖片描述
  • [10] [Tool Call Response]:工具返回班級信息
    在這里插入圖片描述
  • [11] [LLM Request] :客戶端將之前工具調用的所有信息再次返回給模型
    在這里插入圖片描述
  • [12] [LLM Response] :模型最終給出人性化輸出
    在這里插入圖片描述

5.4 最終流程總結

一、初始化階段

  1. 客戶端啟動與工具列表獲取?
    • 用戶首先啟動 MCPClient,完成初始化操作。?
    • MCPClientMCPServer 發送 GET /tools/list 請求,獲取可用工具的元數據。?
    • MCPServer 返回包含工具名稱、功能描述、參數要求等信息的 工具列表JSON,供客戶端后續構建提示詞使用。

二、交互階段

  1. 用戶輸入與提示詞構建?
    • 用戶通過 MCPClient 輸入自然語言請求(如“查詢服務器狀態”“生成文件報告”等)。?
    • MCPClient 將用戶請求與初始化階段獲取的 工具列表 結合,生成包含任務目標和工具能力的提示詞(Prompt),傳遞給LLMService(大語言模型服務層)。?
  2. 工具描述傳遞方式(二選一)?
    • 方式1(Function Call):?
      LLMService 通過 LLM_API 調用大語言模型時,在請求中直接攜帶 工具schema(結構化工具定義,如參數格式、調用格式),告知模型可用工具的調用方式。?
    • 方式2(系統提示詞嵌入):?
      LLMService 將工具列表以自然語言描述形式嵌入 系統提示詞(System Prompt),讓模型在理解用戶需求時知曉可用工具的功能邊界。?
  3. 模型決策與響應解析?
    • LLM_API 返回包含 tool_decision(工具調用決策)的響應:?
      - 若判定 無需工具(如簡單文本回復),響應直接包含最終答案;?
      - 若判定 需要工具(如需要執行本地命令、調用外部接口),響應中包含所需工具的參數要求(如工具名稱、入參格式)。
    • LLMService 解析決策結果,將信息傳遞給 MCPClient
  4. 工具調用分支(需要工具時)
    ?
  • 獲取命令模板MCPClient 根據模型指定的工具名稱,在初始化時保存的工具配置中取出對應的命令模板(如Shell命令格式、API調用參數模板)。?
  • 生成與執行命令MCPClient 將用戶輸入參數與命令模板結合,通過 ToolService(工具執行服務)生成完整可執行命令,并提交給 本地系統 執行。?
    - 結果處理本地系統 返回原始執行結果(如命令輸出文本、API返回數據),ToolService 將其轉換為結構化結果(如JSON格式),反饋給 MCPClient。?
  • 二次調用模型生成最終回復:MCPClient 將結構化結果與用戶原始問題一并提交給 LLMService,通過 LLM_API調用模型,將技術化的執行結果轉化為自然語言描述(如將“服務器CPU使用率80%”轉化為“當前服務器CPU負載較高,建議檢查進程”)。?
  1. 直接回復分支(無需工具時)?
  • 若模型判定無需工具,MCPClient 直接將模型響應顯示給用戶(如簡單的文本問答、信息總結)。

三、最終輸出?
無論是否經過工具調用,MCPClient 最終將處理后的 自然語言結果 呈現給用戶,完成整個交互流程。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/94523.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/94523.shtml
英文地址,請注明出處:http://en.pswp.cn/web/94523.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uniapp安卓真機調試問題解決總結

uniapp安卓真機調試遇到各種連接不上問題&#xff1a; 手機上打開調試數據線不行&#xff0c;換數據線電腦重啟手機重啟拔出數據線&#xff0c;換個USB插口。

Linux Qt創建和調用so庫的詳細教程

一、創建so庫1.文件-->新建文件或項目-->Library->C Library&#xff0c;如下圖2.工程命名為Example3.一直下一步就可以4、工程創建完成&#xff0c;如下圖5、刪除Example_global.h6、配置.pro文件# 設置輸出目錄 DESTDIR $$PWD/output #只生成.so文件 CONFIG plugi…

【深度學習】蒙特卡羅方法:原理、應用與未來趨勢

作者選擇了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰寫的《Deep Learning》(人工智能領域的經典教程&#xff0c;深度學習領域研究生必讀教材),開始深度學習領域學習&#xff0c;深入全面的理解深度學習的理論知識。 之前的文章參考下面的鏈接&#xf…

區塊鏈技術原理(18)-以太坊共識機制

文章目錄前言什么是共識&#xff1f;什么是共識機制&#xff1f;共識機制的核心目標共識機制的類型PoW&#xff08;工作量證明&#xff09;協議&#xff1a;&#xff08;2015-2022&#xff09;PoS&#xff08;權益證明&#xff09;協議&#xff1a;&#xff08;PoS&#xff0c;…

java基礎(十五)計算機網絡

網絡模型概述 為了使得多種設備能通過網絡相互通信&#xff0c;并解決各種不同設備在網絡互聯中的兼容性問題&#xff0c;國際標準化組織&#xff08;ISO&#xff09;制定了開放式系統互聯通信參考模型&#xff08;OSI模型&#xff09;。與此同時&#xff0c;TCP/IP模型作為實際…

idea將服務封裝為一個jar包

你使用的是 IntelliJ IDEA 2018&#xff0c;這個版本雖然不是最新的&#xff0c;但完全支持通過 圖形化界面 打 JAR 包&#xff08;無需命令行&#xff09;&#xff0c;非常適合你在公司內部將 Snowflake 模塊打包成通用組件。下面我將 手把手、一步一步、圖文流程式地教你&…

ZYNQ [Petalinux的運行]

一、下載ubuntu 下載地址很多&#xff0c;這里提供了一個&#xff1a;http://mirrors.aliyun.com/ubuntu-releases/14.04/ 推薦開始瀏覽器下載之后復制下載鏈接使用迅雷下載。 二、虛擬機安裝Ubuntu vmware中安裝Ubutun–這部分不展示 安裝ssh sudo apt install openssh-s…

excel 破解工作表密碼

破解Excel工作表密碼可通過易用寶工具、VBA腳本或修改文件格式實現&#xff0c;具體方法需根據文件類型和密碼保護類型選擇。 ?使用易用寶工具&#xff08;推薦&#xff09;? 適用于Excel 2007及以上版本&#xff0c;操作簡便且無需編程基礎&#xff1a; 下載安裝Excel易用…

Deepseek + RAGFlow 搭建本地知識庫問答系統

Deepseek RAGFlow 搭建本地知識庫問答系統原因為什么要本地部署RAG模型和微調模型區別本地部署流程1. 下載 ollama &#xff0c;通過ollama把Deepseek模型下載到本地運行。2. 下載RAGFlow 源代碼和 Docker &#xff0c;通過Docker部署RAGFlow。3. 在RAGFlow中構建個人知識庫并…

elementui附件上傳自定義文件列表,實現傳完即可預覽、下載、刪除,二次封裝el-upload

背景當前 elementui 的文件上傳組件在上傳完文件之后只支持刪除&#xff0c;用戶希望可以看到附件信息&#xff0c;還可以預覽自己剛剛上傳但未提交的文件&#xff0c;還希望可以下載&#xff0c;因為公司的下載功能當前是通過 OnlyOffice 實現了文件格式轉換&#xff0c;所以我…

linux的conda配置與應用階段的簡單指令備注

1.新建某虛擬環境 conda create -n 虛擬環境名 pythonPython版本號 (-y)2.退出當前虛擬環境 conda deactivate3.查看當前conda環境下所有的虛擬環境 conda info --envs4.查看conda版本和位置 conda --versionwhich conda5.激活某個conda虛擬環境 conda activate 虛擬環境名

虛擬化技術 ——KVM

一、KVM 技術簡介 KVM&#xff08;Kernel-based Virtual Machine&#xff0c;基于內核的虛擬機&#xff09;是 Linux 內核原生支持的全虛擬化解決方案&#xff0c;依托 CPU 的硬件虛擬化技術&#xff08;Intel VT-x/AMD-V&#xff09;實現高效的虛擬機運行。它將 Linux 內核轉…

線程間Bug檢測工具Canary

Canary1.Introduction2.Approach2.1.數據依賴分析2.2.線程間依賴分析3.Bug檢測4.Evaluation參考文獻1.Introduction 主要做跨線程value-flow bug檢查&#xff0c;下面代碼中兩個函數中存在指向關系&#xff1a;1. x→o1x \rightarrow o_1x→o1?, b→o2b \rightarrow o_2b→o2…

AEB 強制來臨,東軟睿馳Next-Cube-Lite有望成為汽車安全普惠“破局器”

AEB 強制時代正在悄然譜寫“普惠安全”的行業底色。日前&#xff0c;備受關注的強制性國家標準《輕型汽車自動緊急制動系統技術要求及試驗方法》&#xff08;以下簡稱“新國標”&#xff09;意見征求階段已經結束。該標準將替代現行國標GB/T 39901-2021&#xff0c;計劃于2028年…

css的white-space: pre

用戶從別的地方復制的配置文件&#xff0c;粘貼到輸入框內&#xff0c;需要保留原始格式發送給后端。核心步驟&#xff1a;### 1. 格式保持機制 - white-space: pre &#xff1a;這是最關鍵的CSS屬性&#xff0c;確保所有空格、制表符、換行符都被保留 - wrap"off" &…

【AI解讀源碼系列】ant design mobile——Space間距

前言 筆者目前業務主要圍繞ant design mobile組件庫來交付H5前端工作。 故此出此專欄來解讀每一個組件是如何實現的。 本文基于AI來解讀Space組件。 文檔鏈接&#xff1a; https://mobile.ant.design/zh/components/space 源碼&#xff1a; https://github.com/ant-design/ant-…

《用餐》,午餐食堂即景小詩分享(手機/小視頻/光盤/養生)

大媽食堂碎碎念&#xff0c;怪罪手機延工期。 筆記模板由python腳本于2025-08-21 19:34:46創建&#xff0c;本篇筆記適合喜歡友善生活和詩的coder翻閱。 學習的細節是歡悅的歷程 博客的核心價值&#xff1a;在于輸出思考與經驗&#xff0c;而不僅僅是知識的簡單復述。 Python官…

高通平臺WIFI學習-- 基于WCN6750 Tri-Band 2x2 MIMO 802.11ax的講解

一 前言: 官方資料顯示WLAN支持如下的Key features ■ Compliant with IEEE 802.11a/b/g/n/ac/ax ■ Supports 2x2 multi-user multiple-input multiple-output (MU-MIMO) ■ Up to 2.9 Gbps data rate (2x2 160 MHz) ■ Tri-band 2.4 GHz/5 GHz/6 GHz support ■ 20 MHz…

javaweb開發筆記——XML_Tomcat10_HTTP

第四章 XML_Tomcat10_HTTP 一 XML XML是EXtensible Markup Language的縮寫&#xff0c;翻譯過來就是可擴展標記語言。所以很明顯&#xff0c;XML和HTML一樣都是標記語言&#xff0c;也就是說它們的基本語法都是標簽。 可擴展 三個字表面上的意思是XML允許自定義格式。但這不代…

Python從入門到自動化運維

文章目錄IPO編程方式、print、input函數print() -- 輸出信息到屏幕input() -- 讀取用戶的輸入基本數據類型int、float、bool、str常用 str 操作方法格式化字符串的三種方式數據驗證方法字符串拼接字符串去重數據類型轉換函數容器類型列表(list)&#xff1a;可變、可重復、有序元…