Spring AI MCP

记于:2025-08-18 下午
地点:浙江省·温州市·家里
天气:晴天

背景#

因项目需要,使用到mcp。

简单介绍 (by AI)#

MCP,全称 Model Context Protocol,是一种用于 大模型与外部服务交互 的协议。它的核心价值在于:
标准化:定义了一致的通信方式,避免为每个外部服务重复造轮子。
多通道支持:可通过 stdio、SSE(Server-Sent Events) 等传输方式进行通信,满足不同运行环境需求。
插件化:MCP Server 可以像插件一样挂载到模型环境中,模型通过协议与之交互,从而获取外部数据或执行操作。
简单来说,MCP 让 模型与外部世界的连接 更加轻量、统一和可扩展。

大致流程#

智能体中配置mcp插件工具,运行智能体,与智能体中d大型对话时,可让其调用mcp插件工具执行相关操作,比如获取当前天气信息,用于接下来的出行任务规划。
上述只是简单的流程描述,具体可以有多种多样的流程与应用方式。

代码和配置#

附上主要代码片段,并做一定说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Slf4j
@Service
public class WeatherMcpService {

/**
* tool: query weather info by city name
*/
@Tool(description = "query weather info by city name")
public String queryWeatherInfo(@ToolParam(required = true, description = "city name") String city) {
String weatherInfo = weatherInfoService.getWeatherInfo(city);
log.info("queryWeatherInfo result: {}", weatherInfo);
return weatherInfo;
}
}

这个mcp工具的作用是查询天气信息。
@Tool注解表示该方法是一个mcp工具方法;
@ToolParam注解用于定义工具方法的参数;

1
2
3
4
5
6
7
8
@Configuration
public class McpServerConfiguration {

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

该类用于配置MCP服务。

1
2
3
4
5
6
7
8
9
10
11
spring:
main:
banner-mode: off
ai:
mcp:
server:
# server.stdio: false # 如果需要可以取消注释
name: my-mcp-server
base-url: /admin
sse-message-endpoint: /mcp/message
version: 1.0.0

这是spring ai mcp server的基本配置。
末尾附上spring ai mcp server官方文档链接。

调试工具#

mcp协议官方提供一个调试mcp server的命令行具;
示例:

1
2
3
4
5
6
7
8
9
10
% npx -y @modelcontextprotocol/inspector
Starting MCP inspector...
⚙️ Proxy server listening on 127.0.0.1:6277
⚠️ WARNING: Authentication is disabled. This is not recommended.
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
New SSE connection request. NOTE: The sse transport is deprecated and has been replaced by StreamableHttp
Query parameters: {"url":"http://localhost:9999/admin/sse","transportType":"sse"}
SSE transport: url=http://localhost:9999/admin/sse, headers={"Accept":"text/event-stream"}
Created client transport
Created server transport

执行上述命令后,打开http://127.0.0.1:6274进行配置、连接和调试。

注意点(重点)#

  • 如果有用到nginx,需要在location部分添加相关配置

    1
    2
    3
    4
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
  • spring boot项目如果配置了context-path,需要在MCP Server的配置中将base-url设置为相应的context-path
    比如context-path: /admin,需要同时设置spring.ai.mcp.server.base-url: /admin
    另外nginx如果还有前缀(非项目本身路径),比如/api,spring.ai.mcp.server.base-url还需要添加/api前缀,比如:/api/admin
    否则会连不上。

  • 还有mcp调试工具经常出现自动断开的问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Error from MCP server: SseError: SSE error: TypeError: terminated: other side closed
    at _eventSource.onerror (file:///Users/yeshimin/.npm/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js:82:31)
    at EventSource.scheduleReconnect_fn (file:///Users/yeshimin/.npm/_npx/5a9d879542beca3a/node_modules/eventsource/dist/index.js:248:53)
    at file:///Users/yeshimin/.npm/_npx/5a9d879542beca3a/node_modules/eventsource/dist/index.js:98:174
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
    code: undefined,
    event: {
    type: 'error',
    message: 'TypeError: terminated: other side closed',
    code: undefined,
    defaultPrevented: false,
    cancelable: false,
    timeStamp: 215334173.374333
    }
    }

    这个也是添加了nginx的proxy_read_timeoutproxy_write_timeout可以解决;
    但是出现了另外的问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Error from MCP server: SseError: SSE error: TypeError: terminated: Body Timeout Error
    at _eventSource.onerror (file:///Users/yeshimin/.npm/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js:82:31)
    at EventSource.scheduleReconnect_fn (file:///Users/yeshimin/.npm/_npx/5a9d879542beca3a/node_modules/eventsource/dist/index.js:248:53)
    at file:///Users/yeshimin/.npm/_npx/5a9d879542beca3a/node_modules/eventsource/dist/index.js:98:174
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
    code: undefined,
    event: {
    type: 'error',
    message: 'TypeError: terminated: Body Timeout Error',
    code: undefined,
    defaultPrevented: false,
    cancelable: false,
    timeStamp: 320434.630833
    }
    }

    这个问了AI,说是长时间未收到服务端的心跳或响应,导致客户端主动断开,该问题暂未解决。

其他#

  • maven配置参考Spring AI Examples项目,包括带鉴权的方式,见下方参考资料;
  • spring ai当前版本1.0.1,还不支持StreamableHttp方式,目前仅支持SSE方式;
  • 智能体的mcp插件集成此处做说明,见具体智能体的文档;

参考资料#