文章目錄
- 前言
- 一、MCP(model context protocol)
- 1.1、概念描述
- 1.2、MCP作用與意義
- 1.3、MCP架構
- 二、使用MCP(model context protocol)
- 2.1、云平臺使用MCP
- 2.2、軟件客戶端使用MCP
- 2.3、Spring AI程序中使用MCP
- 三、Spring AI MCP(model context protocol)開發過程
- 3.1、MCP服務端開發
- 3.2、MCP客戶端開發
- 四、MCP(model context protocol)部署方案
- 五、MCP(model context protocol)安全性
前言
若對您有幫助的話,請點贊收藏加關注哦,您的關注是我持續創作的動力!有問題請私信或聯系郵箱:funian.gm@gmail.com
一、MCP(model context protocol)
1.1、概念描述
- MCP(Model Context Protocol,模型上下文協議)是一種開放標準,目的是增強 AI 與外部系統的交互能力。它為 AI 提供了與外部工具、資源和服務交互的標準化方式,讓 AI 能夠訪問最新數據、執行復雜操作,并與現有系統集成。
- 根據官方定義,MCP 是一種開放協議,它標準化了應用程序如何向大模型提供上下文的方式,可以將 MCP 想象成 AI 應用的 USB 接口,為 AI 模型連接不同的數據源和工具提供了標準化的方法。
-
MCP 協議的 6 大核心概念:
- Resources(資源):服務端向客戶端提供各種數據,如文本、文件、數據庫記錄、API 響應等,客戶端可決定何時使用這些資源,使 AI 能夠訪問最新信息和外部知識,為模型提供更豐富的上下文。
- Prompts(提示詞):服務端定義可復用的提示詞模板和工作流,供客戶端和用戶直接使用,作用是標準化常見的 AI 交互模式,如作為 UI 元素(斜杠命令、快捷操作)呈現給用戶,簡化用戶與 LLM 的交互過程。
- Tools(工具):MCP 中最實用的特性,服務端提供給客戶端可調用的函數,使 AI 模型能夠執行計算、查詢信息或與外部系統交互,極大擴展了 AI 的能力范圍。
- Sampling(采樣):允許服務端通過客戶端向大模型發送生成內容的請求(反向請求),使 MCP 服務能夠實現復雜的智能代理行為,同時保持用戶對整個過程的控制和數據隱私保護。
- Roots(根目錄):MCP 協議的安全機制,定義了服務器可以訪問的文件系統位置,限制訪問范圍,為 MCP 服務提供安全邊界,防止惡意文件訪問。
- Transports(傳輸):定義客戶端和服務器間的通信方式,包括 Stdio(本地進程間通信)和 SSE(網絡實時通信),確保不同環境下的可靠信息交換。
- 開發 MCP 服務,根據MCP官方的描述,主要關注前 3 個概念,其中 Tools 工具是重中之重。
1.2、MCP作用與意義
- MCP 協議的作用和意義:
- 增強 AI 能力:通過 MCP 協議,AI 應用能夠輕松接入他人提供的服務,從而實現更多功能,比如搜索網頁、查詢數據庫、調用第三方 API、執行計算等。
- 作為協議或標準:MCP 本身并不提供具體服務,而是定義了一套規范,讓服務提供者和使用者共同遵守。這類似于 HTTP 協議,能有效降低開發者的理解成本。
- 標準化的好處:以增加 AI 查詢地圖能力為例,若沒有標準化,不同項目或開發者可能會重復開發相關功能,且質量和效果參差不齊。而 MCP 標準化后,官方或第三方可以將查詢地圖能力做成服務,供需要的人直接接入,節省開發成本且效果一致。若更多人開放服務,還能打造服務市場,造福開發者。
- 標準造就生態:這并非新現象,可類比前端的 NPM 包、后端的 Maven 倉庫和 Docker 鏡像源,以及手機應用市場,都是通過標準形成生態,促進資源共享和行業發展。mcp體驗的網址。
1.3、MCP架構
- 宏觀架構:MCP 的核心是 “客戶端 - 服務器” 架構,MCP 客戶端主機可以連接到多個服務器。客戶端主機是指希望訪問 MCP 服務的程序,例如 Claude Desktop、IDE、AI 工具或部署在服務器上的項目。
- MCP 客戶端:MCP Client 是 MCP 架構中的關鍵組件,主要負責和 MCP 服務器建立連接并進行通信。它能自動匹配服務器的協議版本、確認可用功能、負責數據傳輸和 JSON-RPC 交互。此外,它還能發現和使用各種工具、管理資源、和提示詞系統進行交互。除了核心功能,MCP 客戶端還支持根管理、采樣控制以及同步或異步操作等額外特性,并提供多種數據傳輸方式,包括適用于本地調用的 Stdio 標準輸入 / 輸出,以及適用于遠程調用的基于 Java HttpClient 和 WebFlux 的 SSE 傳輸。客戶端可以通過不同傳輸方式調用不同的 MCP 服務,既可以是本地的,也可以是遠程的。
- MCP 服務端:MCP Server 也是整個 MCP 架構的關鍵組件,主要用來為客戶端提供各種工具、資源和功能支持。它負責處理客戶端的請求,包括解析協議、提供工具、管理資源以及處理各種交互信息。同時,它還能記錄日志、發送通知,并且支持多個客戶端同時連接,保證高效的通信和協作。和客戶端一樣,它也可以通過多種方式進行數據傳輸,比如 Stdio 標準輸入 / 輸出、基于 Servlet / WebFlux / WebMVC 的 SSE 傳輸,以滿足不同應用場景。這種設計使得客戶端和服務端完全解耦,任何語言開發的客戶端都可以調用 MCP 服務。
二、使用MCP(model context protocol)
- 使用方式:本節將實戰 3 種使用 MCP 的方式,分別是云平臺使用 MCP、軟件客戶端使用 MCP 和程序中使用 MCP。無論哪種使用方式,原理類似,且有 2 種可選的使用模式,即本地下載 MCP 服務端代碼并運行(類似引入 SDK),或者直接使用已部署的 MCP 服務(類似調用別人的 API)。
- MCP 服務獲取:目前有很多 MCP 服務市場,開發者可以在這些平臺上找到各種現成的 MCP 服務,例如:
- MCP.so:較為主流,提供豐富的 MCP 服務目錄。
- GitHub Awesome MCP Servers:開源 MCP 服務集合。
- 阿里云百煉 MCP 服務市場。
- Spring AI Alibaba 的 MCP 服務市場。
- Glama.ai MCP 服務。
- 其中,絕大多數 MCP 服務市場僅提供本地下載 MCP 服務端代碼并運行的使用方式,因為部署 MCP 服務需要成本。不過,有些云服務平臺提供了云端部署的 MCP 服務,比如阿里云百煉平臺,在線填寫配置后就能使用,可以輕松和平臺上的 AI 應用集成,但一般局限性較大,不太能直接在自己的代碼中使用。
2.1、云平臺使用MCP
- 1、根據阿里云百煉平臺的官方文檔操作。
- 2、登錄阿里云百煉平臺。
- 3、使用高德地圖的MCP服務,開通即可。
- 4、在應用管理添加智能體,進入智能體應用,添加MCP服務。
- 5、測試MCP服務。
2.2、軟件客戶端使用MCP
- 支持情況:不同的客戶端軟件對 MCP 的支持程度不同,可在官方文檔中查看各客戶端支持的特性。
- 以 Cursor 為例的演示:以主流 AI 客戶端 Cursor 為例演示如何使用 MCP 服務,由于沒有現成的部署了 MCP 服務的服務器,采用本地運行的方式。
- 環境準備:首先安裝本地運行 MCP 服務需要用到的工具,具體安裝什么工具取決于 MCP 服務的配置要求。
具體步驟如下:
- 1、MCP 市場找到高德地圖 MCP,發現 Server Config 中定義了使用 npx 命令行工具來安裝和運行服務端代碼。
-
2、從配置中還發現,使用地圖 MCP 需要 API Key,可以到地圖開放平臺創建應用并添加 API Key。
-
3、打開Cursor客戶端的聊天的設置界面。
-
4、添加高德的MCP服務,輸入申請的MCP的API,保存配置。
- 5、使用道德的MCP服務,測試驗證。
2.3、Spring AI程序中使用MCP
- 目標與框架選擇:利用 Spring AI 框架,在程序中使用 MCP 實現一個能夠根據另一半的位置推薦約會地點的 AI 助手。類似的 Java MCP 開發框架還有 Solon AI MCP,但由于更多地使用 Spring 生態,所以推薦使用 Spring AI 框架。
- 學習文檔建議:首先要了解 Spring AI MCP 客戶端的基本使用方法,建議參考 Spring AI Alibaba 的文檔,因為 Spring AI 官方文檔更新太快,包的路徑可能會變動。
- 1、在maven中央倉庫引入依賴。
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency>
- 2、需要在resources目錄下新建一個名為mcp-servers.json的配置文件,用于定義項目中需要用到的 MCP 服務。更改為自己的API_KAY。Windows 環境下的命令配置:在 Windows 環境下,命令配置需要添加.cmd后綴,例如npx.cmd,否則會出現找不到命令的錯誤。
- 3、Spring 配置文件修改:需要修改 Spring 配置文件,編寫 MCP 客戶端配置。由于是本地運行 MCP 服務,所以使用stdio模式,并且要指定 MCP 服務配置文件的位置,具體代碼需后續給出。
spring:ai:mcp:client:stdio:servers-configuration: classpath:mcp-servers.json
- 4、編寫測試代碼。
@Resourceprivate ToolCallbackProvider toolCallbackProvider;/*** AI 旅游報告功能(調用 MCP 服務)** @param message* @param chatId* @return*/public String doChatWithMcp(String message, String chatId) {ChatResponse chatResponse = chatClient.prompt().user(message).advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 20))// 開啟日志,便于觀察效果.advisors(new LoggerAdvisor()).tools(toolCallbackProvider).call().chatResponse();String content = chatResponse.getResult().getOutput().getText();log.info("content: {}", content);return content;}
- 通過自動注入的ToolCallbackProvider獲取到配置中定義的 MCP 服務提供的所有工具,并提供給ChatClient,具體代碼需后續給出。
- MCP 調用的本質,它類似工具調用,并非 AI 服務器主動調用 MCP 服務,而是告訴 AI “MCP 服務提供了哪些工具”,如果 AI 想要使用這些工具完成任務,就會告知后端程序,后端程序在執行工具后將結果返回給 AI,最后由 AI 總結并回復,后續會給出對應的流程圖。
- 5、單元測試。
@Testvoid doChatWithMcp() {String chatId = UUID.randomUUID().toString();// 測試地圖 MCPString message = "幫我搜索成都武侯區的景點圖片";String answer = TravelApp.doChatWithMcp(message, chatId);Assertions.assertNotNull(answer);}
- 6、測試驗證。
三、Spring AI MCP(model context protocol)開發過程
3.1、MCP服務端開發
- 開發基礎:服務端開發主要基于 Spring AI MCP Server Boot Starter,能夠自動配置 MCP 服務端組件,使開發者能夠輕松創建 MCP 服務,向 AI 客戶端提供工具、資源和提示詞模板,從而擴展 AI 模型的能力范圍。
- 引入依賴:Spring AI 提供了 3 種 MCP 服務端 SDK,分別支持非響應式和響應式編程,可根據需要選擇對應的依賴包:
- spring-ai-starter-mcp-server:提供 stdio 傳輸支持,不需要額外的 web 依賴。
- spring-ai-starter-mcp-server-webmvc:提供基于 Spring MVC 的 SSE 傳輸和可選的 stdio 傳輸(一般建議引入這個)。
- spring-ai-starter-mcp-server-webflux:提供基于 Spring WebFlux 的響應式 SSE 傳輸和可選的 stdio 傳輸。
-
圖片搜索的MCP服務自定義開發,步驟如下。
-
1、引入依賴并在 Pexels 網站生成 API Key,在項目根目錄下新建 module(模塊),名稱未完整顯示。注意建議在新項目中單獨打開該模塊,不要直接在原項目的子文件夾中操作,否則可能出現路徑上的問題。引入必要的依賴,包括 Lombok、hutool 工具庫和 Spring AI MCP 服務端依賴。
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency>
- 2、撰寫配置文件。 Stdio、WebMVC SSE 和 WebFlux SSE 三種服務端依賴可以選擇,開發時只需要填寫不同的配置,開發流程都一樣,此處選擇引入 WebMVC。
spring:ai:mcp:server:name: MCP-Serverversion: 0.0.1type: SYNC# stdiostdio: true# stdiomain:web-application-type: nonebanner-mode: off
spring:ai:mcp:server:name: MCP-Serverversion: 0.0.1type: SYNC# stdiostdio: false# stdio
spring:application:name: search-mcp-serverprofiles:active: stdio
server:port: 8127
- 3、開發MCP服務。無論采用哪種傳輸方式,開發 MCP 服務的過程都類似,和開發工具調用一樣,直接使用@Tool注解標記服務類中的方法。注冊 Bean:然后在 Spring Boot 項目啟動時注冊一個ToolCallbackProvider Bean 。
package com.funian.mcpserver.tools;/*** @Auther FuNian* @Major Computer Software*/
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;@Service
public class ImageSearchTool {// 替換為你的 Pexels API 密鑰(需從官網申請)private static final String API_KEY = "自己的API";// Pexels 常規搜索接口(請以文檔為準)private static final String API_URL = "https://api.pexels.com/v1/search";@Tool(description = "search image from web")public String searchImage(@ToolParam(description = "Search query keyword") String query) {try {return String.join(",", searchMediumImages(query));} catch (Exception e) {return "Error search image: " + e.getMessage();}}/*** 搜索中等尺寸的圖片列表** @param query* @return*/public List<String> searchMediumImages(String query) {// 設置請求頭(包含API密鑰)Map<String, String> headers = new HashMap<>();headers.put("Authorization", API_KEY);// 設置請求參數Map<String, Object> params = new HashMap<>();params.put("query", query);// 發送 GET 請求String response = HttpUtil.createGet(API_URL).addHeaders(headers).form(params).execute().body();// 解析響應JSONreturn JSONUtil.parseObj(response).getJSONArray("photos").stream().map(photoObj -> (JSONObject) photoObj).map(photoObj -> photoObj.getJSONObject("src")).map(photo -> photo.getStr("medium")).filter(StrUtil::isNotBlank).collect(Collectors.toList());}
}
package com.funian.mcpserver;import com.funian.mcpserver.tools.ImageSearchTool;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class McpServerApplication {public static void main(String[] args) {SpringApplication.run(McpServerApplication.class, args);}@Beanpublic ToolCallbackProvider imageSearchTools(ImageSearchTool imageSearchTool) {return MethodToolCallbackProvider.builder().toolObjects(imageSearchTool).build();}
}
- 4、單元測試。
package com.funian.mcpserver.tools;import jakarta.annotation.Resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.*;/*** @Auther FuNian* @Major Computer Software*/
@SpringBootTest
class ImageSearchToolTest {@Resourceprivate ImageSearchTool imageSearchTool;@Testvoid searchImage() {String result = imageSearchTool.searchImage("computer");Assertions.assertNotNull(result);}
}
- 5、測試驗證。
- 6、Maven package打包,客戶端會使用Jar包。
3.2、MCP客戶端開發
- 1、引入依賴。
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency>
- 2、測試Stdio方式。
"MCP-Server": {"command": "java","args": ["-Dspring.ai.mcp.server.stdio=true","-Dspring.main.web-application-type=none","-Dlogging.pattern.console=","-jar","MCP-Server/target/MCP-Server-0.0.1-SNAPSHOT.jar"],"env": {}}
- 3、測試驗證。
- 4、測試SSE方式。
spring:ai:mcp:client:sse:connections:server:url: http://localhost:8127# stdio:# servers-configuration: classpath:mcp-servers.json
四、MCP(model context protocol)部署方案
-
分為本地部署和遠程部署:
- 本地部署:適用于 stdio 傳輸方式,流程與開發 MCP 一致,只需將 MCP Server 的代碼打包(如 jar 包),上傳到 MCP Client 可訪問的路徑下,通過編寫對應的 MCP 配置即可啟動。例如后端項目放在服務器 A 上,若項目需要調用 Java 開發的 MCP Server,需將 MCP Server 的可執行 jar 包也放到服務器 A 上。這種方式簡單粗暴,適合小項目,但缺點是每個 MCP 服務都要單獨部署,服務多了會很麻煩。
- 遠程部署:適用于 SSE 傳輸方式,流程與部署后端 web 項目一樣,需在服務器上部署服務(如 jar 包)并運行。
-
Serverless 平臺部署:除了部署到自己的服務器,由于 MCP 服務一般是職責單一的小型項目,很適合部署到 Serverless 平臺。使用該平臺,開發者只需關注業務代碼編寫,無需管理服務器等基礎設施,系統會根據實際使用量自動擴容并按使用付費,顯著降低運維成本和開發復雜。
-
MCP 服務提交至第三方平臺:
- 提交操作:可以把 MCP 服務提交到各種第三方 MCP 服務市場,類似于將應用發布到應用商店,讓其他人也能使用自己的 MCP 服務。
- 好處:這種做法有點像開源,至少可以提升技術影響力、收獲一波流量,這也是大公司在 MCP 服務市場上占坑的原因之一。
五、MCP(model context protocol)安全性
- 安全現狀:MCP 不是一個很安全的協議,安裝使用惡意 MCP 服務可能導致隱私泄露、服務器器權限泄露、服務器被惡意執行腳本等問題。
- 安全問題成因:
- 信息不對稱問題:用戶一般只能看到工具的基本功能描述,不會關注 MCP 服務的源碼及背后指令,而 AI 能看到完整工具描述,包括隱藏在代碼中的指令。惡意開發者可在用戶不知情下通過 AI 操控系統行為,且 AI 僅通過描述了解工具能做什么,不了解實際做了什么。例如開發的搜索圖片服務,源碼中未真正搜索圖片,而是返回垃圾圖片,AI 也無法知曉。
- 上下文混合與隔離不足:所有 MCP 工具描述加載到同一會話上下文中,惡意 MCP 工具可影響其他正常工具行為。例如某惡意 MCP 工具描述為忽視其他提示詞,只輸出特定內容,若拼接進 Prompt 中,會影響 AI 回復,類似 SQL 注入。
- 大模型本身安全意識不足:大模型被設計為精確執行指令,對惡意指令缺乏有效識別和抵抗能力。例如可直接給大模型添加系統預設,改變 AI 回復。
- MCP 協議缺乏嚴格版本控制和更新通知機制:遠程 MCP 服務可在用戶不知情下更改功能或添加惡意代碼,客戶端無法感知。例如惡意 MCP 服務提供的 SSE 調用地址,在用戶不知情時更新服務,繼續調用原地址會遭受攻擊。
- 改進期望:期待 MCP 官方對協議進行改進,包括優化 MCP 服務和工具定義,明確區分功能描述和執行指令;完善權限控制,建立 “最小權限” 原則,涉及敏感數據操作需用戶明確授權;建立安全檢測機制,檢測并禁止工具描述中的惡意指令;規范 MCP 生態,提高 MCP 服務共享門檻,服務市場對上架服務進行安全審計,自動檢測潛在惡意代碼模式。