將您的AI連線到一切:Spring AI的MCP Boot Starters

工程 | Christian Tzolov | 2025年9月16日 | ...

模型上下文協議 (MCP) 規範了AI應用程式如何與外部工具和資源互動。Spring作為主要貢獻者之一,很早就加入了MCP生態系統,幫助開發和維護了官方MCP Java SDK,該SDK是基於Java的MCP實現的基礎。在此貢獻的基礎上,Spring AI透過專用的Boot StartersMCP Java Annotations全面支援MCP,使得構建能夠無縫連線到外部系統的複雜AI驅動應用程式比以往任何時候都更加容易。

本部落格介紹了核心MCP元件,並演示瞭如何使用Spring AI構建MCP伺服器和客戶端,展示了基本和高階功能。完整的原始碼可在以下網址獲取:MCP天氣示例

注意:此內容僅適用於Spring AI 1.1.0-SNAPSHOT 或 Spring AI 1.1.0-M1+ 版本。

什麼是模型上下文協議?

模型上下文協議 (MCP) 是一種標準化協議,使AI模型能夠以結構化的方式與外部工具和資源互動。可以將其視為AI模型與現實世界之間的橋樑——允許它們透過一致的介面訪問資料庫、API、檔案系統和其他外部服務。

MCP客戶端-伺服器架構

isolated

模型上下文協議遵循客戶端-伺服器架構,確保了關注點的明確分離。MCP伺服器從第三方服務中暴露特定的功能(工具、資源、提示)。MCP客戶端由宿主應用程式例項化,用於與特定的MCP伺服器通訊。每個客戶端處理與一個伺服器的一次直接通訊。

宿主是使用者互動的AI應用程式,而客戶端是實現伺服器連線的協議級元件。

MCP協議確保客戶端和伺服器之間完全、語言無關的互操作性。您可以擁有用Java、Python或TypeScript編寫的客戶端,與用任何語言編寫的伺服器進行通訊,反之亦然。

這種架構在客戶端和伺服器端開發之間建立了明確的界限和責任,自然地形成了兩個不同的開發者社群。

AI應用程式/宿主開發者

處理協調多個MCP伺服器(透過MCP客戶端連線)並與AI模型整合的複雜性。AI開發者構建AI應用程式,這些應用程式

  • 使用MCP客戶端消費來自多個MCP伺服器的功能
  • 處理AI模型整合和提示工程
  • 管理對話上下文和使用者互動
  • 協調跨不同服務的複雜工作流
  • 專注於創造引人入勝的使用者體驗

MCP伺服器(提供者)開發者

專注於將第三方服務中的特定功能(工具、資源、提示)作為MCP伺服器暴露。伺服器開發者建立的伺服器

  • 封裝第三方服務和API(資料庫、檔案系統、外部API)
  • 透過標準化的MCP原語(工具、資源、提示)暴露服務功能
  • 處理其特定服務的認證和授權

這種分離確保了伺服器開發者可以專注於封裝其領域特定服務,而無需擔心AI編排。同時,AI應用程式開發者可以利用現有的MCP伺服器,而無需瞭解每個第三方服務的複雜性。

這種分工意味著資料庫專家可以為PostgreSQL建立一個MCP伺服器,而無需理解LLM提示,而AI應用程式開發者可以使用該PostgreSQL伺服器,而無需瞭解SQL內部機制。MCP協議充當了它們之間的通用語言。

Spring AI透過MCP客戶端MCP伺服器Boot Starters支援這種架構。這意味著Spring開發者可以參與MCP生態系統的兩方面——構建消費MCP伺服器的AI應用程式,以及建立將基於Spring的服務暴露給更廣泛AI社群的MCP伺服器。

MCP功能

MCP Capabilities

客戶端和伺服器共享,MCP提供了一套廣泛的功能,使AI應用程式和外部服務之間能夠無縫通訊。

重要:工具由LLM擁有,與其他MCP功能(如提示和資源)不同。LLM(而不是宿主)決定何時、以何種順序呼叫工具。宿主只控制哪些工具描述提供給LLM。

構建MCP伺服器

讓我們構建一個提供即時天氣預報資訊的可流式HTTP MCP伺服器

Spring Boot伺服器應用程式

建立一個新的 (mcp-weather-server) Spring Boot應用程式

@SpringBootApplication
public class McpServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(McpServerApplication.class, args);
	}
}

帶有Spring AI MCP伺服器依賴
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>

瞭解更多關於可用的伺服器依賴選項

application.properties中啟用可流式HTTP伺服器傳輸

spring.ai.mcp.server.protocol=STREAMABLE

您可以使用STREAMABLESTATELESSSSE傳輸啟動伺服器。要啟用STDIO傳輸,您需要設定spring.ai.mcp.server.stdio=true


天氣服務

利用免費的天氣REST API構建一個能夠透過位置座標檢索天氣預報的服務。

新增@McpTool和@McpToolParam註解以將getTemperature方法註冊為MCP伺服器工具

@Service
public class WeatherService {

	public record WeatherResponse(Current current) {
		public record Current(LocalDateTime time, int interval, double temperature_2m) {}
	}

	@McpTool(description = "Get the temperature (in celsius) for a specific location")
	public WeatherResponse getTemperature(
      @McpToolParam(description = "The location latitude") double latitude,
      @McpToolParam(description = "The location longitude") double longitude) {

		return RestClient.create()
				.get()
				.uri("https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m",
						latitude, longitude)
				.retrieve()
				.body(WeatherResponse.class);
	}
}

構建和執行

./mvnw clean install -DskipTests

java -jar target/mcp-weather-server-0.0.1-SNAPSHOT.jar

這將在埠8080上啟動mcp-weather-server。

使用MCP伺服器

MCP天氣伺服器啟動並執行後,您可以使用各種符合MCP的客戶端應用程式與之互動

MCP檢查器

MCP檢查器是一個互動式開發工具,用於測試和除錯MCP伺服器。要啟動檢查器,請執行

npx @modelcontextprotocol/inspector

在瀏覽器UI中,將傳輸型別設定為Streamable HTTP,URL設定為https://:8080/mcp。點選Connect建立連線。然後列出工具並執行getTemperature。

MCP Capabilities

MCP Java SDK

使用MCP Java SDK客戶端以程式設計方式連線到伺服器

var client = McpClient.sync(
HttpClientStreamableHttpTransport
	.builder("https://:8080").build())
.build();

client.initialize();

CallToolResult weather = client.callTool(
	new CallToolRequest("getTemperature", 
			Map.of("latitude", "47.6062", 
					"longitude", "-122.3321")));

其他符合MCP的AI應用程式/SDK

將您的MCP伺服器連線到流行的AI應用程式


Claude桌面版

要與Claude桌面版整合,使用本地STDIO傳輸,請在Claude桌面版設定中新增以下配置

{
 "mcpServers": {
  "spring-ai-mcp-weather": {
  "command": "java",
  "args": [
	"-Dspring.ai.mcp.server.stdio=true",
	"-Dspring.main.web-application-type=none",
	"-Dlogging.pattern.console=",
	"-jar",
	"/path/to/mcp-weather-server-0.0.1.jar"]
  }
 }
}

/absolute/path/to/替換為您的構建JAR檔案的實際路徑。

請遵循Claude桌面版的MCP伺服器安裝以獲取進一步指導。Claude桌面版的免費版本不支援取樣!




MCP Claude Desktop

高階伺服器功能

讓我們擴充套件我們的MCP天氣伺服器,以演示包括日誌、進度跟蹤和取樣在內的高階MCP功能。這些功能實現了伺服器和客戶端之間豐富的互動

  • 日誌:向連線的客戶端傳送結構化日誌訊息以進行除錯和監控
  • 進度跟蹤:報告長時間執行操作的即時進度更新
  • 取樣:請求客戶端的LLM根據伺服器資料生成內容

在這個增強版本中,我們的天氣伺服器將向客戶端記錄其操作以實現透明度,在獲取和處理天氣資料時報告進度,並請求客戶端的LLM生成一首關於天氣預報的史詩般詩歌。

這是更新後的伺服器實現

@Service
public class WeatherService {

	public record WeatherResponse(Current current) {
		public record Current(LocalDateTime time, int interval, double temperature_2m) {}
	}

	@McpTool(description = "Get the temperature (in celsius) for a specific location")
	public String getTemperature(
			McpSyncServerExchange exchange, // (1)
			@McpToolParam(description = "The location latitude") double latitude,
			@McpToolParam(description = "The location longitude") double longitude,
			@McpProgressToken String progressToken) { // (2)

		exchange.loggingNotification(LoggingMessageNotification.builder() // (3)
			.level(LoggingLevel.DEBUG)
			.data("Call getTemperature Tool with latitude: " + latitude + " and longitude: " + longitude)
			.meta(Map.of()) // non null meta as a workaround for bug: ...
			.build());

		WeatherResponse weatherResponse = RestClient.create()
				.get()
				.uri("https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m",
						latitude, longitude)
				.retrieve()
				.body(WeatherResponse.class);
		

		String epicPoem = "MCP Client doesn't provide sampling capability.";

		if (exchange.getClientCapabilities().sampling() != null) {
			// 50% progress
			exchange.progressNotification(new ProgressNotification(progressToken, 0.5, 1.0, "Start sampling"));	// (4)

			String samplingMessage = """
					For a weather forecast (temperature is in Celsius): %s.
					At location with latitude: %s and longitude: %s.
					Please write an epic poem about this forecast using a Shakespearean style.
					""".formatted(weatherResponse.current().temperature_2m(), latitude, longitude);

			CreateMessageResult samplingResponse = exchange.createMessage(CreateMessageRequest.builder()
					.systemPrompt("You are a poet!")
					.messages(List.of(new SamplingMessage(Role.USER, new TextContent(samplingMessage))))
					.build()); // (5)

			epicPoem = ((TextContent) samplingResponse.content()).text();
		}	
		
		// 100% progress
		exchange.progressNotification(new ProgressNotification(progressToken, 1.0, 1.0, "Task completed"));

		return """
			Weather Poem: %s			
			about the weather: %s°C at location: (%s, %s)		
			""".formatted(epicPoem, weatherResponse.current().temperature_2m(), latitude, longitude);
  }
}
  1. McpSyncServerExchange - exchange引數提供對伺服器-客戶端通訊功能的訪問。它允許伺服器傳送通知並向客戶端發出請求。

  2. @ProgressToken - progressToken引數啟用進度跟蹤。客戶端提供此令牌,伺服器使用它傳送進度更新。

  3. 日誌通知 - 向客戶端傳送結構化日誌訊息以進行除錯和監控。

  4. 進度更新 - 向客戶端報告操作進度(在本例中為50%),並附帶描述性訊息。

MCP Capabilities

  1. 取樣功能 - 最強大的功能 - 伺服器可以請求客戶端的LLM生成內容。

這允許伺服器利用客戶端的AI功能,建立雙向AI互動模式。

增強後的天氣服務現在不僅返回天氣資料,還返回一首關於天氣預報的創意詩歌,展示了MCP伺服器和AI模型之間強大的協同作用。

構建MCP客戶端

讓我們構建一個使用LLM並透過MCP客戶端連線到MCP伺服器的AI應用程式。

客戶端配置

建立一個新的Spring Boot專案 (mcp-weather-client),並新增以下依賴

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-starter-model-anthropic</artifactId>
</dependency>

瞭解關於可用依賴選項以配置不同的傳輸機制。

application.yml中,配置與MCP伺服器的連線

spring:
  main:
    web-application-type: none

  ai:
    # Set credentials for your Anthropic API account
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}

    # Connect to the MCP Weather Server using streamable-http client transport
    mcp:
      client:
        streamable-http:
          connections:
            my-weather-server:
              url: https://:8080    

請注意,配置已為伺服器連線分配了my-weather-server名稱。

Spring Boot客戶端應用程式

建立一個使用連線到LLM和MCP天氣伺服器的ChatClient的客戶端應用程式。

@SpringBootApplication
public class McpClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(McpClientApplication.class, args).close(); // (1)
	}

	@Bean
	public ChatClient chatClient(ChatClient.Builder chatClientBuilder) { // (2)
		return chatClientBuilder.build();
	}

	String userPrompt = """
		Check the weather in Amsterdam right now and show the creative response!
		Please incorporate all creative responses from all LLM providers.
		""";

	@Bean
	public CommandLineRunner predefinedQuestions(ChatClient chatClient, ToolCallbackProvider mcpToolProvider) { // (3)
		return args -> System.out.println(
			chatClient.prompt(userPrompt) // (4)
				.toolContext(Map.of("progressToken", "token-" + new Random().nextInt())) // (5)
				.toolCallbacks(mcpToolProvider) // (6)
				.call()
				.content());
	}
}
  1. 應用程式生命週期管理 - 應用程式啟動、執行天氣查詢、顯示結果,然後乾淨地退出。

  2. ChatClient配置 - 使用Spring AI的自動配置構建器建立一個已配置的ChatClient bean。構建器會自動填充

    • AI模型配置(在本例中為Anthropic Claude)
    • application.properties中的預設設定和配置
  3. CommandLineRunner - 在應用程式上下文完全載入後自動執行。它注入了已配置的ChatClient用於AI模型互動,以及包含所有已註冊的MCP工具的ToolCallbackProvider,這些工具來自連線的伺服器。

  4. AI提示 - 指示AI模型獲取阿姆斯特丹的當前天氣。AI模型會根據提示自動發現並呼叫適當的MCP工具。

  5. 進度令牌 - 使用toolContext將唯一的progressToken傳遞給帶有@McpProgressToken引數註解的MCP工具。

  6. MCP工具整合 - 這條關鍵行將ChatClient連線到所有可用的MCP工具

  • mcpToolProvider由Spring AI的MCP客戶端啟動器自動配置
  • 包含來自已連線MCP伺服器的所有工具(透過spring.ai.mcp.client.*.connections.*配置)
  • AI模型可以在對話期間自動發現並呼叫這些工具

客戶端MCP處理器

建立一個服務類來處理來自伺服器的MCP通知和請求。這些處理器是我們在上面實現的高階伺服器功能的客戶端對應部分,實現了MCP伺服器和客戶端之間的雙向通訊。

@Service
public class McpClientHandlers {

	private static final Logger logger = LoggerFactory.getLogger(McpClientHandlers.class);

	private final ChatClient chatClient;

	public McpClientHandlers(@Lazy ChatClient chatClient) { // Lazy is needed to avoid circular dependency
		this.chatClient = chatClient;
	}

	@McpProgress(clients = "my-weather-server") // (1)
	public void progressHandler(ProgressNotification progressNotification) {
		logger.info("MCP PROGRESS: [{}] progress: {} total: {} message: {}",
				progressNotification.progressToken(), progressNotification.progress(),
				progressNotification.total(), progressNotification.message());
	}

	@McpLogging(clients = "my-weather-server")
	public void loggingHandler(LoggingMessageNotification loggingMessage) {
		logger.info("MCP LOGGING: [{}] {}", loggingMessage.level(), loggingMessage.data());
	}

	@McpSampling(clients = "my-weather-server")
	public CreateMessageResult samplingHandler(CreateMessageRequest llmRequest) {

		logger.info("MCP SAMPLING: {}", llmRequest);

		String llmResponse = chatClient
				.prompt()
				.system(llmRequest.systemPrompt())
				.user(((TextContent) llmRequest.messages().get(0).content()).text())
				.call()
				.content();

		return CreateMessageResult.builder().content(new TextContent(llmResponse)).build();
	}
}

理解處理器元件
  1. 進度處理器 - 接收來自伺服器長時間執行操作的即時進度更新。當伺服器呼叫exchange.progressNotification(...)時觸發。例如,天氣伺服器在開始取樣時傳送50%的進度,完成時傳送100%。通常用於顯示進度條、更新UI狀態或記錄操作進度。

  2. 日誌處理器 - 接收來自伺服器的結構化日誌訊息以進行除錯和監控。當伺服器呼叫exchange.loggingNotification(...)時觸發。例如,天氣伺服器記錄“呼叫getTemperature工具,緯度:X,經度:Y”。用於除錯伺服器操作、審計跟蹤或監控儀表板。

  3. 取樣處理器 - 最強大的功能。它使伺服器能夠從客戶端的LLM請求AI生成的內容。用於雙向AI互動、創意內容生成、動態響應。當伺服器呼叫帶有采樣功能檢查的exchange.createMessage(...)時觸發。執行流程如下

    • 如果客戶端支援取樣,則請求一首關於天氣的詩歌
    • 客戶端處理器接收請求並使用其ChatClient與LLM互動並生成詩歌
    • 生成的詩歌返回給伺服器併合併到最終的工具響應中
關鍵設計模式
  • 基於註解的路由clients = "my-weather-server"屬性確保處理器僅處理來自配置中定義的特定MCP伺服器連線的通知:spring.ai.mcp.client.streamable-http.connections.[my-weather-server].url

    如果您的應用程式連線到多個MCP伺服器,請使用clients屬性將每個處理器分配給相應的MCP客戶端。

    @McpProgress(clients = {"weather-server", "database-server"})  // Handle progress from multiple servers
    public void multiServerProgressHandler(ProgressNotification notification) {
    	// Handle progress from both servers
    }
    
    @McpSampling(clients = "specialized-ai-server")  // Handle sampling from specific server
    public CreateMessageResult specializedSamplingHandler(CreateMessageRequest request) {
    	// Handle sampling requests from specialized AI server
    }
    
  • ChatClient上的@Lazy註解可以防止在ChatClient也依賴於MCP元件時可能出現的迴圈依賴問題。

  • 雙向AI通訊:取樣處理器建立了一個強大的模式,其中

    • 伺服器(領域專家)可以利用客戶端的AI功能

    • 客戶端的LLM根據伺服器提供的上下文生成創意內容

    • 這實現了超越簡單工具呼叫的複雜AI-AI互動

      這種架構使MCP客戶端成為伺服器操作中的反應式參與者,實現了複雜的互動,而不僅僅是被動的工具消費。

多個MCP伺服器

使用不同的傳輸連線到多個MCP伺服器。以下是如何在您的天氣伺服器旁邊新增Brave搜尋MCP伺服器進行網頁搜尋的示例

MCP Demo

spring:
  ai:
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}
    mcp:
      client:
        streamable-http:
          connections:
            my-weather-server:
              url: https://:8080        
        stdio:
          connections:
            brave-search:
              command: npx
              args: ["-y", 
				"@modelcontextprotocol/server-brave-search"]

它使用STDIO客戶端傳輸。

現在您的LLM可以在單個提示中結合天氣資料和網頁搜尋

String userPrompt = """
	Check the weather in Amsterdam and show the creative response!
	Please incorporate all creative responses.
	
	Then search online to find publishers for poetry and list top 3.
	""";

構建並執行

確保您的MCP天氣伺服器已啟動並執行。

然後構建並啟動您的客戶端

./mvnw clean install -DskipTests

java -jar target/mcp-weather-client-0.0.1-SNAPSHOT.jar

結論

Spring成熟的開發模型與MCP標準化協議的結合,為下一代AI應用程式奠定了堅實的基礎。無論您是構建聊天機器人、資料分析工具還是開發助手,Spring AI的MCP支援都能為您提供所需的構建塊。

本介紹涵蓋了基本的MCP概念,並演示瞭如何使用Spring AI的Boot Starters構建MCP伺服器和客戶端,並實現了基本的工具功能。然而,MCP生態系統提供了更復雜的功能,我們將在未來的部落格文章中進行探討。

  • Java MCP註解深入探討:學習如何利用Spring AI的基於註解的方法建立更易於維護和宣告式的MCP實現,包括高階註解模式和最佳實踐。

  • 超越工具 - 提示、資源和補全:探索如何實現MCP的全套功能,包括共享提示模板、動態資源提供和智慧自動補全功能,這些功能使您的MCP伺服器更加使用者友好和強大。

  • 授權支援 - 保護MCP伺服器:使用OAuth 2保護您的MCP伺服器,並確保只有授權使用者才能訪問工具、資源和其他功能。為您的MCP客戶端新增授權支援,以便它們可以獲取OAuth 2令牌以與安全的MCP伺服器進行身份驗證。

準備好開始了嗎?檢視示例應用程式,探索Spring AI和MCP與AI整合的全部潛力。

其他資源


有關最新更新和全面文件,請訪問Spring AI參考文件

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有