Spring AI 中的 MCP 註解概述
1. 概述
模型上下文協定 (MCP)已成為連接 AI 模型與外部資料和工具的標準。 MCP 使開發人員能夠創建可在各種 AI 用戶端上運行的通用連接器,而無需為每個資料來源建立客製化整合。 Spring AI 透過一個專用模組支援此協議,該模組引入了一種聲明式、基於註解的程式設計模型。我們無需手動註冊工具回呼或配置 JSON 模式,只需註解標準 Java 方法即可將其作為 AI 功能公開。
在本教程中,我們將探索 Spring AI 中的核心 MCP 註解: @McpTool 、 @McpResource和*@McpPrompt。*
2. 依賴關係和配置
截至 2026 年初,Spring AI MCP 伺服器功能已在 Milestone 和 Snapshot 程式碼庫中提供。這意味著這些構件尚未發佈到中央 Maven 程式碼庫,因此我們需要配置專案才能找到它們。
2.1. Maven 倉庫
由於 MCP 元件目前處於積極開發階段(預發布版),我們需要明確地將 Spring Milestone 和 Snapshot 倉庫新增至建置配置中。否則,Maven 將無法解析spring-ai-starter-mcp-server依賴項:
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases><enabled>false</enabled></releases>
</repository>
</repositories>
2.2. 啟動器依賴項
我們使用[spring-ai-starter-mcp-server](https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-mcp-server-spring-boot-starter)依賴項。此啟動器負責 MCP bean 的自動設定和元件掃描:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
<version>1.0.0-M6</version>
</dependency>
2.3 伺服器配置
MCP 伺服器在本地運行時通常透過標準輸入/輸出 (Stdio) 進行通訊。這意味著 AI 用戶端會將我們的 Java 應用程式作為子進程啟動,並透過控制台與其「對話」。
為了實現這一點,我們的應用程式不能向控制台列印任何日誌,因為這會破壞協定 JSON 訊息。
我們需要設定application.properties文件,使其使用標準輸入輸出 (Stdio) 並屏蔽日誌:
spring.application.name=my-spring-calculator
# 1. Use STDIO transport
spring.ai.mcp.server.stdio=true
# 2. CRITICAL: Disable the Banner and Web Server
# Any text printed to console will break the connection
spring.main.banner-mode=off
spring.main.web-application-type=none
# 3. Redirect logs away from Console
logging.pattern.console=
3. 使用@McpTool公開功能
@McpTool註解是 MCP 開發的核心。它將 Java 方法標記為 AI 模型可以呼叫的可執行「工具」。應用程式啟動時,Spring AI 會分析方法簽章以建立工具定義。
3.1 基本工具定義
我們來創建一個服務,該服務公開一個簡單的計算器功能。我們在方法上使用*@McpTool註解,在參數上使用@McpToolParam*註解來提供元資料。
@Service
public class CalculatorService {
@McpTool(
name = "calculate_sum",
description = "Calculates the sum of two integers. Useful for basic arithmetic."
)
public int add(
@McpToolParam(description = "The first number to add", required = true) int a,
@McpToolParam(description = "The second number to add", required = true) int b
) {
return a + b;
}
}
描述欄位在功能上非常重要。 LLM 使用它們來了解何時調用此工具以及參數代表什麼。如果省略名稱,則預設使用方法名稱。
3.2 處理複雜對象
對於更複雜的工具,我們通常需要傳遞結構化物件而非簡單的基本類型。 Spring AI 支援 Java Record(以及 POJO),並能自動將其序列化為 JSON 模式。例如,考慮一個接受篩選條件的客戶搜尋工具:
public record CustomerSearchCriteria(
String region,
boolean activeOnly,
@JsonProperty(required = false) Integer limit
) {}
@Service
public class CustomerService {
@McpTool(description = "Search for customers using structured criteria")
public List<String> searchCustomers(
@McpToolParam(description = "The search filters") CustomerSearchCriteria criteria
) {
// In a real app, this would query a database
return List.of("Customer A", "Customer B");
}
}
透過使用記錄(Record),我們可以對相關參數進行分組。 AI 用戶端會收到一個模式(schema),該模式指示它應該發送一個包含 region 和 activeOnly 欄位的 JSON 物件。
3.3 存取請求上下文
有時,工具需要存取底層 MCP 會話,例如,將訊息記錄回客戶端或追蹤進度。我們可以將McpSyncRequestContext作為參數注入。此參數屬於內部基礎架構,不會包含在 AI 可見的已生成工具架構中。
@McpTool(name = "long_running_process")
public String processData(
String dataId,
McpSyncRequestContext context
) {
context.info("Starting processing for ID: " + dataId);
// Simulate work and report detailed progress
// 50% complete (0.5 out of 1.0)
context.progress(p -> p.progress(0.5).total(1.0).message("Processing records..."));
return "Processed " + dataId;
}
3.4. 使用@McpComplete啟用自動完成功能
像 Claude 這樣的現代 AI 用戶端支援使用者在提示字元中輸入參數時自動補全。 @McpComplete註解允許我們提供動態建議。例如,我們可以為review_code提示字元建議程式語言:
@McpComplete(prompt = "review_code")
public List<String> completeLanguage(McpSchema.CompleteRequest.CompleteArgument argument) {
if (!"language".equals(argument.name())) {
return List.of();
}
String token = argument.value();
return List.of("Java", "Python", "TypeScript", "Go").stream()
.filter(lang -> lang.toLowerCase().startsWith(token.toLowerCase()))
.toList();
}
Spring AI 將此方法與review_code提示關聯起來。當使用者選擇該提示並在語言欄位中開始輸入時,此方法會過濾建議。
4. 使用@McpResource公開數據
工具代表操作,資源代表資料。 `@ McpResource註解以唯讀形式將資料暴露給 AI,類似於 AI 讀取檔案的方式。每個資源都被指派一個 URI。
4.1. URI模板
我們可以使用 URI 模板來建立動態資源。 Spring AI 會從 URI 模板中提取變量,並將它們對應到方法參數。
@Service
public class SystemLogService {
@McpResource(
uri = "logs://{serviceName}/{date}",
name = "System Logs",
description = "Read logs for a specific service and date"
)
public String readLog(
@McpToolParam(description = "Service Name") String serviceName,
@McpToolParam(description = "Date YYYY-MM-DD") String date
) {
return "Logs for " + serviceName + " on " + date + ": No errors found.";
}
}
當 AI 用戶端請求logs://payment-service/2023-12-0 1 時,將使用提取的值呼叫此方法。
4.2. 返回二進位數據
資源不僅可以包含文字。若要提供二進位資料(例如影像或 PDF),該方法應傳回 ReadResourceResult 物件。這樣我們就可以明確設定 MIME 類型。
@McpResource(uri = "diagrams://{id}", name = "System Architecture Diagram")
public ReadResourceResult getDiagram(String id) {
String base64Image = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=";
return new ReadResourceResult(List.of(
new BlobResourceContents(
"diagrams://" + id,
"image/png",
base64Image
)
));
}
5. 使用@McpPrompt標準化提示
@McpPrompt註解允許伺服器定義可重複使用的提示範本。這對於共享與伺服器資料互動的標準化說明或「最佳實踐」非常有用:
@Service
public class CodeReviewPrompts {
@McpPrompt(
name = "review_code",
description = "Generates a standard code review request"
)
public GetPromptResult generateReviewPrompt(
@McpArg(name = "language", description = "The programming language", required = true) String language,
@McpArg(name = "code", description = "The code snippet", required = true) String code
) {
String template = """
Please review the following %s code.
Focus on thread safety and performance:
%s
""";
String content = String.format(template, language, code);
return new GetPromptResult(
"Code Review",
List.of(new PromptMessage(Role.USER, new TextContent(content)))
);
}
}
在這裡,@ McpArg註解的作用與McpToolParam類似,它定義了客戶端必須提供的變數來填入模板。
6. 連接到 Claude Desktop
Claude桌面應用程式充當MCP客戶端。要將其連接到我們的Spring Boot伺服器,我們必須將其配置為直接啟動我們的JAR檔案。
6.1 建構應用程式
因為我們使用的是標準輸入輸出(Stdio),所以我們需要一個可運行的 JAR 檔案。我們將使用 Maven 建置應用程式:
./mvnw clean package
請確認 JAR 檔案是否存在於target/目錄中(例如,target/mcp-demo-0.0.1-SNAPSHOT.jar)。
6.2 配置 Claude Desktop
要設定 MCP 連接,我們需要開啟claude_desktop_config.json檔案。我們可以透過 Claude UI 輕鬆存取此文件,方法是導航至“設定”>“開發者”,然後按一下“編輯配置”。或者,我們也可以直接在以下路徑找到該檔案:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
打開伺服器後,我們需要新增伺服器配置:
{
"mcpServers": {
"my-spring-calculator": {
"command": "java",
"args": [
"-jar",
"C:\Users\yourname\projects\mcp-demo\target\mcp-demo-0.0.1-SNAPSHOT.jar"
]
}
}
}
如果使用 Windows 系統,則必須轉義反斜線。例如,如果實際路徑是C:\Users\me\app.jar ,則在 JSON 檔案中必須將其寫成C:\\Users\\me\\app.jar 。
儲存檔案後,我們必須完全重新啟動 Claude 桌面應用程式才能使變更生效。重新啟動後,我們在輸入列中尋找連接器(插頭圖示)—應該可以看到 my-spring-calculator,其狀態為綠色且處於活動狀態。
7. 結論
在本文中,我們討論了 Spring AI MCP 註釋,它顯著降低了建構智慧體 AI 系統的門檻。
透過利用諸如@Service和@McpTool等熟悉的註解,開發者可以輕鬆地將現有的業務邏輯暴露給 AI 模型。我們探討了@McpTool如何將方法轉換為 AI 可調用的操作, @McpResource如何為 AI 上下文創建虛擬文件系統,以及@McpPrompt如何規範交互。此外,由於這些元件仍然是普通的 Java 物件 (POJO),因此可以使用標準的 Java 測試實務輕鬆進行測試。