首页 / Spring AI 入门教程 / MCP Server 开发

Spring AI 入门教程

MCP Server 开发

本教程共 45 篇 · 第 29 篇 · 更新于 2026-08-16 · 约 7 分钟阅读

Spring AIMCPMCP Server@ToolBoot StarterSTDIOSTREAMABLEToolCallbackProvider

本节目标:把一个 Spring Boot 应用变成 MCP 服务器,把 @Tool 方法暴露成 MCP 工具,并了解配置和启动方式。学完你就能开发自己的 MCP 服务器,给任何 MCP 客户端提供能力。

29.1 选 Starter

服务器端有三个 Starter,按传输方式选。

spring-ai-starter-mcp-server 是 STDIO 服务器。程序被客户端当子进程启动,用标准输入输出通信。适合命令行工具、桌面工具集成,不需要 Web 容器。

spring-ai-starter-mcp-server-webmvc 和 spring-ai-starter-mcp-server-webflux 是 HTTP 服务器,前者基于 Spring MVC,后者基于响应式 WebFlux。SSE、Streamable-HTTP、Stateless 三种协议都用这两个 Starter,靠配置切换。

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

项目里同时有 spring-boot-starter-web 和 webflux 时,Spring Boot 会优先用 DispatcherServlet。这种情况建议选 webmvc 版 starter,别混。

三个 Starter 的能力是一致的,差异只在传输层。换 Starter 不需要改业务代码,改依赖和配置就行。

29.2 用 @Tool 暴露工具

第 24 章讲过 @Tool。在 MCP 服务器里,@Tool 方法会被自动转换成 MCP 工具,供远程客户端发现和调用。

@Service
public class WeatherService {

    @Tool(description = "Get weather information by city name")
    public String getWeather(String cityName) {
        return "Current weather in " + cityName + ": sunny, 22°C";
    }
}

光有方法还不够,要把工具注册给框架。最常用的方式是 MethodToolCallbackProvider 包装对象里的 @Tool 方法,声明成 ToolCallbackProvider Bean:

@SpringBootApplication
public class McpServerApplication {

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

    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
    }
}

自动配置会扫描三类 Bean:单个 ToolCallback、ToolCallback 列表、ToolCallbackProvider,把它们全部注册成 MCP 工具。同名工具只保留第一个。不需要转换时,把 spring.ai.mcp.server.tool-callback-converter 设为 false 即可关闭。

多个业务类都想暴露工具?MethodToolCallbackProvider 的 toolObjects 可以传多个对象,也可以声明多个 ToolCallbackProvider Bean,自动配置会把它们合并。注意 Spring AI 2.0 里工具调用统一走 ToolCallback API,老版本的 FunctionCallback 已废弃,别混用。

Tip

除了 @Tool,还可以用 @McpTool 注解直接声明 MCP 工具。两者都能暴露工具,@McpTool 的写法更贴近 MCP 概念,还能用 @McpToolParam 精细控制参数描述和必填性,第 31 章细讲。

29.3 配置服务器

启动方式取决于传输协议。STDIO 服务器用 stdio 开关:

spring:
  ai:
    mcp:
      server:
        stdio: true
        name: weather-stdio-server
        version: 1.0.0
        type: SYNC

HTTP 服务器用 protocol 属性选协议。SSE 从 2.0 起标记弃用,新项目用 STREAMABLE:

spring:
  ai:
    mcp:
      server:
        protocol: STREAMABLE
        name: weather-mcp-server
        version: 1.0.0
        type: SYNC
        capabilities:
          tool: true
          resource: true
          prompt: true
          completion: true

capabilities 控制暴露哪些能力,默认全开。关了某个能力,服务器就不会注册和暴露对应的功能。

type 可选 SYNC 或 ASYNC,默认 SYNC。SYNC 服务器只注册同步方法,返回 Mono/Flux 的异步方法会被跳过(忽略);ASYNC 反过来。写代码时让方法风格和 type 保持一致,避免方法被静默过滤。

HTTP 服务器还有一些路径配置。SSE 协议默认 sse-endpoint=/sse、sse-message-endpoint=/mcp/message;Streamable-HTTP 默认 streamable-http.mcp-endpoint=/mcp。需要自定义就配对应属性。keep-alive-interval 可以开启心跳,默认关闭。

还有个属性值得知道:instructions。它给客户端一段说明文字,告诉对方这个服务器提供什么、怎么用,客户端可以把它呈现给用户或模型。对工具较多的服务器,写清楚 instructions 能明显提升调用准确率。

29.4 启动和验证

STDIO 服务器直接运行 main 方法即可,它会等待客户端通过标准输入发起对话。注意 STDIO 服务器没有端口,无法用浏览器访问,必须由客户端拉起。

HTTP 服务器就是普通 Web 应用,启动后监听端口。验证方式有两种。

第一种,用官方 MCP Inspector 工具调试。它能可视化地查看工具列表、发起工具调用,是开发期排查问题的利器。

第二种,写一个客户端连接它。第 28 章讲过客户端配置,把 streamable-http 连接的 url 指向本机端口:

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            weather-server:
              url: http://localhost:8080

启动客户端后,在对话里问天气问题,看远程工具是否被调用。

调试 STDIO 服务器有个小技巧:先手动跑一遍启动命令,确认程序本身能正常工作,再交给客户端拉起。因为 STDIO 没有日志文件,程序打印到标准输出的内容都会变成协议消息,普通 System.out 调试输出会污染协议流。排查时优先用日志框架写文件。

HTTP 服务器就好办得多。工具没生效时先看两件事:一是 /mcp 端点能不能访问,二是客户端配置的连接名和端点对不对。再不行,用 curl 直接发一个 initialize 请求,看服务器回不回应。

29.5 服务器还能提供什么

除了工具,服务器还能暴露资源和提示词,用低层 API 注册。

资源对应 McpServerFeatures.SyncResourceSpecification,一个资源含 URI、描述和读取回调。提示词对应 SyncPromptSpecification,返回 GetPromptResult。自动补全对应 SyncCompletionSpecification。这些都声明成 Bean,自动配置会统一处理。

资源和提示词不是必须的。大多数服务器只要工具就够,客户端也只把工具接进模型。什么时候需要资源?模型需要读取服务端的结构化数据时。什么时候需要提示词?想把领域提示词沉淀在服务端、多个客户端共用时。

工具执行时还支持 ToolContext,里面装着 McpSyncServerExchange。通过它可以给客户端发日志通知、进度通知,比如长任务跑了一半先报个进度。工具变化时,服务器还能发变更通知,让客户端及时刷新工具列表。这块偏进阶,用到时查官方文档。

还有两个开关值得知道。expose-mcp-client-tools 默认 false,设为 true 后,本服务器可以把下游 MCP 客户端拿到的工具再暴露出去,实现服务器级联。tool-response-mime-type 按工具名指定响应 MIME 类型,比如图片生成工具返回 image/png,客户端就知道按图片处理。

29.6 一个常见问题

“我写了 @Tool 方法,客户端却看不到工具”是最高频的坑。排查顺序:

  1. 确认 ToolCallbackProvider Bean 存在,且 toolObjects 传了正确的对象。
  2. 确认服务器 type 和方法返回类型匹配:SYNC 配普通方法,ASYNC 配 Mono/Flux。
  3. 确认客户端连的是对的协议和端点,特别是自定义过 mcp-endpoint 的。
  4. 留意启动日志,确认方法没有被过滤掉。

29.7 小结

开发 MCP 服务器三步:选 Starter、写 @Tool 方法并注册 ToolCallbackProvider、按传输方式配置。STDIO 服务器跑在客户端拉起的子进程里,HTTP 服务器就是普通 Web 应用。工具、资源、提示词都能暴露,客户端发现即用。