Spring AI MCP注释服务器示例
 ](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
这个示例项目演示了如何使用Spring AI的MCP注释创建MCP服务器。它展示了MCP服务器功能的全面实现,包括使用Java注释的干净、声明性方法的工具、资源、提示和完成。
有关更多信息,请参阅 MCP服务器启动启动器 参考文件。
目录
概述
该示例展示了一个全面的MCP服务器实现,包括:
- 集成
spring-ai-starter-mcp-server-webmvc - 支持SSE(服务器发送事件)和STDIO传输
- 使用注释自动注册MCP功能:
- @Tool Spring AI工具注册 - @McpTool 用于MCP特定工具注册 - @McpResource 用于资源注册 - @McpPrompt 快速注册 - @McpComplete 完成注册
- 每种能力类型的综合示例
特性
此示例演示了:
- 天气工具 -使用Spring AI检索天气预报和警报的工具
@Tool和MCP@McpTool注释 - 用户配置文件资源 -用于访问具有各种URI模式的用户配置文件信息的资源
- 快速生成 -针对不同用例的各种提示模板
- 自动完成 -用户名和国家的完成建议
依赖项
该项目需要Spring AI MCP服务器WebVC引导启动器和MCP注释:
org.springframework.ai
spring-ai-starter-mcp-server-webmvc
这些依赖关系提供:
- 基于Spring MVC的HTTP传输(
WebMvcSseServerTransport) - 自动配置的SSE、可流式HTTP或无状态端点,由配置
spring.ai.mcp.server.protocol=...财产和违约SSE. - 可选STDIO传输,如果
spring.ai.mcp.server.stdio=true已设置 - MCP操作的基于注释的方法处理
建设项目
使用Maven构建项目:
./mvnw clean install -DskipTests运行服务器
服务器支持两种传输模式:
WebVC SSE/流式HTTP/无状态模式
模式取决于 spring.ai.mcp.server.protocol=... 设置。
java -Dspring.ai.mcp.server.protocol=STREAMABLE -jar target/mcp-annotations-server-0.0.1-SNAPSHOT.jarSTDIO模式
要启用STDIO传输,请设置相应的属性:
java -Dspring.ai.mcp.server.stdio=true -Dspring.main.web-application-type=none -jar target/mcp-annotations-server-0.0.1-SNAPSHOT.jar配置
通过配置服务器 application.properties:
# Server identification
spring.ai.mcp.server.name=my-weather-server
spring.ai.mcp.server.version=0.0.1
spring.ai.mcp.server.protocol=STREAMABLE
# spring.ai.mcp.server.protocol=STATELESS
# Transport configuration (uncomment to enable STDIO)
# spring.ai.mcp.server.stdio=true
# spring.main.web-application-type=none
# Logging (required for STDIO transport)
spring.main.banner-mode=off
# logging.pattern.console=
# Log file location
logging.file.name=./model-context-protocol/mcp-annotations/mcp-annotations-server/target/server.log服务器实现
服务器使用Spring Boot和MCP注释自动注册功能:
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
// (Optional) not MCP annotation. Just demostrates how to use the @Tool along with the @McpTool to provision MCP Server Tools.
@Bean
public ToolCallbackProvider weatherTools(SpringAiToolProvider weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
}MCP能力
工具
该项目包括两个不同的工具提供商,展示了不同的注释方法:
SpringAiToolProvider(Spring AI@Tool注释)
使用Spring AI @Tool 天气相关工具的注释:
@Service
public class SpringAiToolProvider {
@Tool(description = "Get weather forecast for a specific latitude/longitude")
public String getWeatherForecastByLocation(double latitude, double longitude) {
// Implementation using weather.gov API
}
@Tool(description = "Get weather alerts for a US state. Input is Two-letter US state code (e.g., CA, NY)")
public String getAlerts(String state) {
// Implementation using weather.gov API
}
}McpToolProvider(MCP@McpTool注释)
使用MCP特定 @McpTool 温度检索注释:
@Service
public class McpToolProvider {
@McpTool(description = "Get the temperature (in celsius) for a specific location")
public WeatherResponse getTemperature(McpSyncServerExchange exchange,
@McpProgressToken String progressToken
@McpToolParam(description = "The location latitude") double latitude,
@McpToolParam(description = "The location longitude") double longitude,
@McpToolParam(description = "The city name") String city) {
// Implementation using open-meteo.com API
}
}可用工具
- 天气预报工具 (春天AI)
- 姓名: getWeatherForecastByLocation - 描述:获取特定纬度/经度的天气预报 - 参数: - latitude:双纬度坐标 - longitude:双经度坐标
- 天气警报工具 (春天AI)
- 姓名: getAlerts - 描述:获取美国某个州的天气警报 - 参数: - state:String-两个字母的美国州代码(例如,CA、NY)
- 温度工具 (MCP)
- 姓名: getTemperature - 描述:获取特定位置的温度(单位:摄氏度) - 参数: - latitude:double-位置纬度 - longitude:double-位置经度 - city:String-城市名称
资源
这 UserProfileResourceProvider 使用实现资源访问 @McpResource 带综合示例的注释:
@Service
public class UserProfileResourceProvider {
@McpResource(uri = "user-profile://{username}",
name = "User Profile",
description = "Provides user profile information for a specific user")
public ReadResourceResult getUserProfile(ReadResourceRequest request, String username) {
// Implementation to retrieve user profile
}
// Additional resource methods...
}可用资源
- 用户档案
- URI: user-profile://{username} - 描述:为特定用户提供用户配置文件信息
- 用户详情
- URI: user-profile://{username} - 描述:使用URI变量提供用户详细信息
- 用户属性
- URI: user-attribute://{username}/{attribute} - 描述:提供用户配置文件中的特定属性
- Exchange用户配置文件
- URI: user-profile-exchange://{username} - 描述:提供具有服务器交换上下文的用户配置文件
- 用户连接
- URI: user-connections://{username} - 描述:为用户提供连接列表
- 用户通知
- URI: user-notifications://{username} - 说明:为用户提供通知
- 用户状态
- URI: user-status://{username} - 描述:提供用户的当前状态
- 用户位置
- URI: user-location://{username} - 描述:为用户提供当前位置
- 用户化身
- URI: user-avatar://{username} - 描述:为用户提供base64编码的头像图像 - MIME类型: image/png
示例用户数据
提供者为用户提供了示例数据: john, jane, bob,以及 alice 配置文件包含姓名、电子邮件、年龄和位置信息。
提示
这 PromptProvider 使用实现提示生成 @McpPrompt 注释:
@Service
public class PromptProvider {
@McpPrompt(name = "greeting", description = "A simple greeting prompt")
public GetPromptResult greetingPrompt(
@McpArg(name = "name", description = "The name to greet", required = true) String name) {
// Implementation to generate greeting prompt
}
// Additional prompt methods...
}可用提示
- 问候
- 姓名: greeting - 描述:一个简单的问候提示 - 参数: - name:String-要问候的名字(必填)
- 个性化消息
- 姓名: personalized-message - 描述:根据用户信息生成个性化消息 - 参数: - name:String-用户名(必填) - age:Integer-用户的年龄(可选) - interests:String-用户的兴趣(可选)
- 开场白
- 姓名: conversation-starter - 说明:提供与系统的对话启动器
- 地图参数
- 姓名: map-arguments - 说明:演示如何使用映射作为参数
- 单一消息
- 姓名: single-message - 描述:演示返回单个PromptMessage - 参数: - name:String-用户名(必填)
- 字符串列表
- 姓名: string-list - 说明:演示返回字符串列表 - 参数: - topic:String-提供信息的主题(必填)
补全
这 AutocompleteProvider 使用实现自动完成 @McpComplete 注释:
@Service
public class AutocompleteProvider {
@McpComplete(uri = "user-status://{username}")
public List completeUsername(String usernamePrefix) {
// Implementation to provide username completions
}
// Additional completion methods...
}可用完工量
- 用户名填写
- URI: user-status://{username} - 根据前缀为用户名提供完成建议
- 名称完成
- 提示: personalized-message - 在个性化消息提示中为姓名提供完成建议
- 国家名称填写
- 提示: travel-planner - 提供国家名称的填写建议 - 退货: CompleteResult 附竣工详图
MCP客户端
您可以使用STDIO或SSE传输连接到服务器:
启动启动器客户端
为了获得更好的开发体验,请考虑使用 MCP客户端启动程序 及相关的 MCP客户端注释 支持。
MCP客户端引导启动器提供:
- MCP客户端连接的自动配置
- 基于声明性注释的服务器通知处理程序
- 支持多种传输协议(SSE、流式HTTP、STDIO)
- 客户端处理程序的自动注册
客户端依赖关系
将MCP客户端引导启动器添加到您的项目中:
org.springframework.ai
spring-ai-starter-mcp-client
客户端注释
客户端支持多种注释来处理服务器通知:
@McpLogging-处理来自MCP服务器的日志消息通知@McpProgress-处理长时间运行的操作的进度通知@McpSampling-处理来自MCP服务器的LLM完成采样请求@McpElicitation-处理启发请求,从用户那里收集更多信息@McpToolListChanged-处理服务器工具列表更改时的通知@McpResourceListChanged-处理服务器资源列表更改时的通知@McpPromptListChanged-当服务器的提示列表更改时处理通知
重要:所有MCP客户端注释 必须 包括a clients 参数,用于将处理程序与特定的MCP客户端连接相关联。
客户端实现示例
@SpringBootApplication
public class McpClientApplication {
public static void main(String[] args) {
SpringApplication.run(McpClientApplication.class, args).close();
}
@Bean
public CommandLineRunner predefinedQuestions(List mcpClients) {
return args -> {
for (McpSyncClient mcpClient : mcpClients) {
System.out.println(">>> MCP Client: " + mcpClient.getClientInfo());
// Call a tool that sends progress notifications
CallToolRequest toolRequest = CallToolRequest.builder()
.name("tool1")
.arguments(Map.of("input", "test input"))
.progressToken("test-progress-token")
.build();
CallToolResult response = mcpClient.callTool(toolRequest);
System.out.println("Tool response: " + response);
}
};
}
}客户端处理程序提供者
@Service
public class McpClientHandlerProviders {
private static final Logger logger = LoggerFactory.getLogger(McpClientHandlerProviders.class);
@McpProgress(clients = "server1")
public void progressHandler(ProgressNotification progressNotification) {
logger.info("MCP PROGRESS: [{}] progress: {} total: {} message: {}",
progressNotification.progressToken(), progressNotification.progress(),
progressNotification.total(), progressNotification.message());
}
@McpLogging(clients = "server1")
public void loggingHandler(LoggingMessageNotification loggingMessage) {
logger.info("MCP LOGGING: [{}] {}", loggingMessage.level(), loggingMessage.data());
}
@McpSampling(clients = "server1")
public CreateMessageResult samplingHandler(CreateMessageRequest llmRequest) {
logger.info("MCP SAMPLING: {}", llmRequest);
String userPrompt = ((McpSchema.TextContent) llmRequest.messages().get(0).content()).text();
String modelHint = llmRequest.modelPreferences().hints().get(0).name();
return CreateMessageResult.builder()
.content(new McpSchema.TextContent("Response " + userPrompt + " with model hint " + modelHint))
.build();
}
@McpElicitation(clients = "server1")
public ElicitResult elicitationHandler(McpSchema.ElicitRequest request) {
logger.info("MCP ELICITATION: {}", request);
return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message()));
}
}客户端配置
在中配置客户端连接 application.properties:
spring.application.name=mcp
spring.main.web-application-type=none
# Streamable-HTTP transport configuration
spring.ai.mcp.client.streamable-http.connections.server1.url=http://localhost:8080
# SSE transport configuration (alternative)
# spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080
# Global client settings
spring.ai.mcp.client.request-timeout=5m
# Logging configuration
logging.level.io.modelcontextprotocol.client=WARN
logging.level.io.modelcontextprotocol.spec=WARN
# Optional: Disable tool callback if not needed
# spring.ai.mcp.client.toolcallback.enabled=false运行客户端示例
流式HTTP(HttpClient)传输
- 启动MCP注释服务器:
java -Dspring.ai.mcp.server.protocol=STREAMABLE -jar mcp-annotations-server-0.0.1-SNAPSHOT.jar- 在另一个控制台中,启动配置了Streamable HTTP传输的客户端:
java -Dspring.ai.mcp.client.streamable-http.connections.server1.url=http://localhost:8080 \
-jar mcp-annotations-client-0.0.1-SNAPSHOT.jar苏格兰和南方能源公司运输
- 使用SSE协议启动MCP注释服务器:
java -Dspring.ai.mcp.server.protocol=SSE -jar mcp-annotations-server-0.0.1-SNAPSHOT.jar- 启动配置了SSE传输的客户端:
java -Dspring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080 \
-jar mcp-annotations-client-0.0.1-SNAPSHOT.jar注: 这 clients="server1" 参数 @McpLogging, @McpSampling, @McpProgress 和 @McpElicitate 注释与您在文档中输入的连接名称相对应 spring.ai.mcp.client.streamable-http.connections.server1.url= 或 spring.ai.mcp.client.sse.connections.server1.url= 配置。
STDIO传输
- 创建一个
mcp-servers-config.json配置文件:
{
"mcpServers": {
"annotations-server": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dspring.main.web-application-type=none",
"-Dlogging.pattern.console=",
"-jar",
"/absolute/path/to/mcp-annotations-server-0.0.1-SNAPSHOT.jar"
]
}
}
}- 使用配置文件运行客户端:
java -Dspring.ai.mcp.client.stdio.servers-configuration=file:mcp-servers-config.json \
-Dlogging.pattern.console= \
-jar mcp-annotations-client-0.0.1-SNAPSHOT.jar客户端将自动:
- 连接到已配置的MCP服务器
- 基于以下内容注册带注释的处理程序
clients参数 - 通过带注释的方法处理服务器通知和请求
- 按配置提供日志记录和进度更新
