首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >spring-ai 学习系列(5)-MCP(webflux sse)

spring-ai 学习系列(5)-MCP(webflux sse)

作者头像
菩提树下的杨过
发布2025-08-22 08:33:14
发布2025-08-22 08:33:14
22600
代码可运行
举报
运行总次数:0
代码可运行

前面学习了stdio模式的MCP使用,可以看到这种方式局限性比较大,mcp host/mcp client/mcp server通常要在同1台机器上,使用进程间通讯。更常见的做法是,大家各自部署自己的mcp server,就象常规后端http api一样,想部署在哪都行,只要http能访问即可。

一、调整pom依赖

代码语言:javascript
代码运行次数:0
运行
复制
1 <dependency>
2     <groupId>org.springframework.ai</groupId>
3     <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
4     <version>1.0.0</version>
5 </dependency>

MCP Server的代码相对stdio模式而言,完全不用改!

二、调整yaml

代码语言:javascript
代码运行次数:0
运行
复制
spring:
  ai:
    mcp:
      server:
        type: async

启动MCP Server,如果访问http://localhost:8080/sse看到类似以下界面,说明启动成功

三、MCP Client

代码语言:javascript
代码运行次数:0
运行
复制
    public static void main(String[] args) {
        WebFluxSseClientTransport webFluxSseTransport = new WebFluxSseClientTransport(WebClient.builder().baseUrl("http://localhost:8080"));

        McpSyncClient mcpClient = McpClient.sync(webFluxSseTransport).build();

        McpSchema.InitializeResult initialize = mcpClient.initialize();
        System.out.println("initialize=>" + initialize);

        Object ping = mcpClient.ping();
        System.out.println("ping=>" + ping);

        McpSchema.ListToolsResult toolsList = mcpClient.listTools();

        System.out.println(toolsList);

        McpSchema.CallToolResult orderStatus = mcpClient.callTool(
                new McpSchema.CallToolRequest("queryOrderStatus",
                        Map.of("orderNo", "25070601")));
        System.out.println(orderStatus);

        mcpClient.closeGracefully();
    }

Client运行后,会看到类似输出:

代码语言:javascript
代码运行次数:0
运行
复制
20:50:03.897 [reactor-http-nio-2] INFO io.modelcontextprotocol.client.McpAsyncClient -- Server response with Protocol: 2024-11-05, Capabilities: ServerCapabilities[completions=CompletionCapabilities[], experimental=null, logging=LoggingCapabilities[], prompts=PromptCapabilities[listChanged=true], resources=ResourceCapabilities[subscribe=false, listChanged=true], tools=ToolCapabilities[listChanged=true]], Info: Implementation[name=mcp-server, version=1.0.0] and Instructions null
initialize=>InitializeResult[protocolVersion=2024-11-05, capabilities=ServerCapabilities[completions=CompletionCapabilities[], experimental=null, logging=LoggingCapabilities[], prompts=PromptCapabilities[listChanged=true], resources=ResourceCapabilities[subscribe=false, listChanged=true], tools=ToolCapabilities[listChanged=true]], serverInfo=Implementation[name=mcp-server, version=1.0.0], instructions=null]
ping=>{}
ListToolsResult[tools=[Tool[name=queryOrderStatus, description=根据订单号查询订单状态, inputSchema=JsonSchema[type=object, properties={orderNo={type=string, description=订单号,格式为8位数字,比如:25070601}}, required=[orderNo], additionalProperties=false, defs=null, definitions=null]]], nextCursor=null]
CallToolResult[content=[TextContent[audience=null, priority=null, text="订单号:25070601,订单状态:已发货"]], isError=false]

Process finished with exit code 0

四、在MCP Host中使用MCP Server

仍然以Cherry Studio为例,添加MCP server后,点保存(前提:MCP Server应对的url http://localhost:8080/sse 必须能正常访问)

注:点保存时,cherry studio会向 http://localhost:8080/sse,发送几次请求([参考上一节的分析](https://www.cnblogs.com/yjmyzz/p/18980212/spring-ai-learn-mcp-lifecycle)),可用wireshark之类的抓包工具验证

  • 第1次是get 请求

/sse会返回1个sessionId值99e64481-8190-4e17-ba64-05404b9131 (相当于与mcp server建立了长连接,后面的所有post请求,都会用到这个sessionId)

  • 第2次post请求 initialize

json请求如下:

代码语言:javascript
代码运行次数:0
运行
复制
 1 {
 2     "method": "initialize",
 3     "params": {
 4         "protocolVersion": "2025-03-26",
 5         "capabilities": {},
 6         "clientInfo": {
 7             "name": "Cherry Studio",
 8             "version": "1.4.8"
 9         }
10     },
11     "jsonrpc": "2.0",
12     "id": 0
13 }
  • 第3次post请求 notifications/initialized
代码语言:javascript
代码运行次数:0
运行
复制
{
    "method": "notifications/initialized",
    "jsonrpc": "2.0"
}
  • 第4/5/6次post请求 ping(即:连ping 3次, 这里可能是我本机网络不好,cherry studio重试了几次,每次请求后,id值返回会+1,下一次请求时,入参里的id,必须是上次返回的id值)
代码语言:javascript
代码运行次数:0
运行
复制
{
    "method": "ping",
    "jsonrpc": "2.0",
    "id": 1
}
  • 第7次post请求 resources/list
代码语言:javascript
代码运行次数:0
运行
复制
{
    "method": "resources/list",
    "jsonrpc": "2.0",
    "id": 6
}
  • 第8次post请求 tools/list
代码语言:javascript
代码运行次数:0
运行
复制
{
    "method": "tools/list",
    "jsonrpc": "2.0",
    "id": 4
}
  • 第9次post请求 prompts/list
代码语言:javascript
代码运行次数:0
运行
复制
{
    "method": "prompts/list",
    "jsonrpc": "2.0",
    "id": 5
}

大家有兴趣的话,可以自行用postman或apipost之类的工具,一步步手动发送post请求,模拟这个过程,观察/sse的页面输出

互此,cherry studio已知道了mcp sever的所有信息,后面的会话中,就能使用该工具了。

文中代码:https://github.com/yjmyzz/spring-ai-sample/tree/day04

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档