mcpField
S
spring-ai-mcp-server-patterns

spring-ai-mcp-server-patterns

github.com/giuseppe-trisciuoglio开发3653.8k 次安装7 周前更新
代码仓库

关于 spring-ai-mcp-server-patterns

面向使用 Spring AI 构建 MCP 服务的 Java 开发者,提供从工具和提示模板定义到传输配置、安全与测试的实现模式。

主要功能

  1. 01用 @Tool 声明工具处理方法
  2. 02用 @PromptTemplate 定义提示模板
  3. 03配置 stdio、HTTP 和 SSE 传输
  4. 04为工具添加输入校验与安全控制
  5. 05参考集成测试和完整示例

适用场景

  1. 01构建 Spring Boot MCP 服务
  2. 02向客户端提供数据库或 API 工具
  3. 03为工具端点配置访问控制

MCP 相关

指导使用 Spring AI 实现 MCP 服务,向 MCP 客户端提供工具和提示模板,并配置 stdio、HTTP 或 SSE 传输。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-ai-mcp-server-patterns

安装后在 Claude Code 中输入/spring-ai-mcp-server-patterns确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
advanced-patterns.md
api-reference.md
examples.md
implementation-patterns.md
migration-guide.md
testing-guide.md
references/templates/
tool-template.java

详细介绍

Spring AI MCP 服务实现模式

使用 Spring AI 实现 MCP 服务,支持 AI 函数调用、工具处理器和 MCP 传输配置。

概述

适用于生产环境的 MCP 服务模式:@Tool 函数、@PromptTemplate 资源,以及使用 Spring AI 安全机制的 stdio/HTTP/SSE 传输方式。

适用场景

MCP 服务、Spring AI 函数调用、AI 工具、工具调用、自定义工具处理器、Spring Boot MCP、资源端点或 MCP 传输配置。

快速参考

核心注解
注解目标用途
@EnableMcpServer类启用 MCP 服务自动配置
@Tool(description)方法声明可供 AI 调用的工具
@ToolParam(value)参数为 AI 说明工具参数
@PromptTemplate(name)方法声明可复用的提示词模板
@PromptParam(value)参数说明提示词参数
传输类型
传输方式适用场景配置
stdio本地进程 / Claude Desktop默认
http远程 HTTP 客户端port、path
sse实时流式客户端port、path
关键依赖

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-server</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
    <version>1.0.0</version>
</dependency>
// Gradle
implementation 'org.springframework.ai:spring-ai-mcp-server:1.0.0'
implementation 'org.springframework.ai:spring-ai-starter-model-openai:1.0.0'

说明

1. 项目设置

添加 Spring AI MCP 依赖(参见上方的快速参考),在 application.properties 中配置 AI 模型,并使用 @EnableMcpServer 启用 MCP:

@SpringBootApplication
@EnableMcpServer
public class MyMcpApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyMcpApplication.class, args);
    }
}
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.mcp.enabled=true
spring.ai.mcp.transport.type=stdio
2. 定义工具

在 @Component Bean 中使用 @Tool 注解方法。使用 @ToolParam 说明参数:

@Component
public class WeatherTools {

    @Tool(description = "Get current weather for a city")
    public WeatherData getWeather(@ToolParam("City name") String city) {
        return weatherService.getCurrentWeather(city);
    }

    @Tool(description = "Get 5-day forecast for a city")
    public ForecastData getForecast(
            @ToolParam("City name") String city,
            @ToolParam(value = "Unit: celsius or fahrenheit", required = false) String unit) {
        return weatherService.getForecast(city, unit != null ? unit : "celsius");
    }
}

数据库工具、API 集成工具以及底层 FunctionCallback 模式,请参见 references/implementation-patterns.md。

3. 创建提示词模板
@Component
public class CodeReviewPrompts {

    @PromptTemplate(
        name = "java-code-review",
        description = "Review Java code for best practices and issues"
    )
    public Prompt createCodeReviewPrompt(
            @PromptParam("code") String code,
            @PromptParam(value = "focusAreas", required = false) List<String> focusAreas) {

        String focus = focusAreas != null ? String.join(", ", focusAreas) : "general best practices";
        return Prompt.builder()
                .system("You are an expert Java code reviewer with 20 years of experience.")
                .user("Review the following Java code for " + focus + ":\n```java\n" + code + "\n```")
                .build();
    }
}

更多提示词模板模式,请参见 references/implementation-patterns.md。

4. 配置传输方式
spring:
  ai:
    mcp:
      enabled: true
      transport:
        type: stdio       # stdio | http | sse
        http:
          port: 8080
          path: /mcp
      server:
        name: my-mcp-server
        version: 1.0.0
5. 添加安全机制
@Configuration
public class McpSecurityConfig {

    @Bean
    public ToolFilter toolFilter(SecurityService securityService) {
        return (tool, context) -> {
            User user = securityService.getCurrentUser();
            if (tool.name().startsWith("admin_")) {
                return user.hasRole("ADMIN");
            }
            return securityService.isToolAllowed(user, tool.name());
        };
    }
}

在工具方法上使用 @PreAuthorize("hasRole('ADMIN')") 实现方法级安全控制。完整的安全模式请参见 references/implementation-patterns.md。

6. 测试
@SpringBootTest
class WeatherToolsTest {

    @Autowired
    private WeatherTools weatherTools;

    @MockBean
    private WeatherService weatherService;

    @Test
    void testGetWeather_Success() {
        when(weatherService.getCurrentWeather("London"))
            .thenReturn(new WeatherData("London", "Cloudy", 15.0));

        WeatherData result = weatherTools.getWeather("London");

        assertThat(result.city()).isEqualTo("London");
        verify(weatherService).getCurrentWeather("London");
    }
}

集成测试、Testcontainers、安全测试和切片测试,请参见 references/testing-guide.md。

最佳实践

工具设计
  • 保持工具功能专一——每个工具只执行一项操作
  • 使用清晰、以操作为导向的名称(getWeather、executeQuery)
  • 始终使用 @ToolParam 为参数添加注解,并提供描述性文本
  • 返回结构化记录/DTO,而不是原始字符串或映射
  • 尽可能将工具设计为幂等
安全
  • 验证并清理所有输入——AI 生成的参数并不可信
  • SQL 使用参数化查询;文件工具应验证并规范化路径
  • 对敏感工具使用 @PreAuthorize 实施基于角色的访问控制
  • 对所有修改数据的工具执行记录审计日志
  • 切勿在工具描述或错误消息中暴露凭据或敏感数据
性能
  • 对开销较大的操作使用 @Cacheable,并设置适当的 TTL
  • 为所有外部调用设置超时
  • 对长时间运行的操作使用 @Async
  • 使用 Micrometer 指标进行监控
错误处理
  • 返回结构化错误响应,并提供对用户友好的消息
  • 记录上下文(用户、工具名称、参数)以便调试
  • 为暂时性故障实现重试逻辑
  • 使用 @ControllerAdvice 实现一致的错误响应

示例

示例 1:最简天气 MCP 服务
@SpringBootApplication
@EnableMcpServer
public class WeatherMcpApplication {
    public static void main(String[] args) {
        SpringApplication.run(WeatherMcpApplication.class, args);
    }
}

@Component
public class WeatherTools {

    @Tool(description = "Get current weather for a city")
    public WeatherData getWeather(@ToolParam("City name") String city) {
        return new WeatherData(city, "Sunny", 22.5);
    }
}

record WeatherData(String city, String condition, double temperatureCelsius) {}
示例 2:安全的数据库工具
@Component
@PreAuthorize("hasRole('USER')")
public class DatabaseTools {

    private final JdbcTemplate jdbcTemplate;

    @Tool(description = "Execute a read-only SQL query and return results")
    public QueryResult executeQuery(
            @ToolParam("SQL SELECT query") String sql,
            @ToolParam(value = "Parameters as JSON map", required = false) String paramsJson) {

        if (!sql.trim().toUpperCase().startsWith("SELECT")) {
            throw new IllegalArgumentException("Only SELECT queries are allowed");
        }
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
        return new QueryResult(rows, rows.size());
    }
}

完整示例包括文件系统工具、REST API 集成和提示词模板服务,请参见 references/examples.md。

限制和警告

安全
  • 绝不泄露工具描述、参数或错误消息中的敏感数据
  • 必须验证输入——执行前务必进行验证
  • 外部内容不可信——获取 URL 的工具可能会收到提示词注入载荷;请验证所有获取的内容
  • SQL 注入:只能使用参数化查询
  • 路径遍历:规范化所有文件路径,并验证其是否位于基础路径内
运行
  • 响应应简洁——过长的响应可能超出 AI 上下文窗口限制
  • 所有工具都必须实现超时机制;默认值应可配置
  • 对开销较大的操作进行速率限制
  • 工具可能会被并发调用——请确保线程安全
Spring AI 特定事项
  • Spring AI 正在积极开发中——在生产环境中固定使用特定版本
  • 工具抛出的错误消息会暴露给 AI 模型;请对其进行清理
  • 谨慎选择传输类型:本地进程使用 stdio,远程客户端使用 http/sse

参考资料

请查阅以下文件,了解详细模式和示例:

评论

支持 Markdown