摘要:最近这段时间有个 AI 相关的概念特别火,叫 MCP,全称模型上下文协议(Model Context Protocol)。这是由 Anthropic 推出的一项开放标准,目标是为大型语言模型和 AI 助手提供一个统一、标准化的接口,使 AI 能够轻松操作外部工
最近这段时间有个 AI 相关的概念特别火,叫 MCP,全称模型上下文协议(Model Context Protocol)。这是由 Anthropic 推出的一项开放标准,目标是为大型语言模型和 AI 助手提供一个统一、标准化的接口,使 AI 能够轻松操作外部工具并完成更复杂的任务。
这篇文章,就带大家速通 MCP,了解其核心概念,并且以我们给自己产品 面试鸭 开发的面试搜题 MCP 服务为例,带大家实战 MCP 服务端和客户端的开发!
开源指路:https://github.com/yuyuanweb/mcp-mianshiya-server
以前,如果想让 AI 处理我们的数据,基本只能靠预训练数据或者上传数据,既麻烦又低效。而且,就算是很强大的 AI 模型,也会有数据隔离的问题,无法直接访问新数据,每次有新的数据进来,都要重新训练或上传,扩展起来比较困难。
现在,MCP 解决了这个问题,它突破了模型对静态知识库的依赖,使其具备更强的动态交互能力,能够像人类一样调用搜索引擎、访问本地文件、连接 API 服务,甚至直接操作第三方库。所以 MCP 相当于在 AI 和数据之间架起了一座桥。更重要的是,只要大家都遵循 MCP 这套协议,AI 就能无缝连接本地数据、互联网资源、开发工具、生产力软件,甚至整个社区生态,实现真正的“万物互联”,这将极大提升 AI 的协作和工作能力,价值不可估量。
MCP 的核心是 “客户端 - 服务器” 架构,其中 MCP 客户端主机可以连接到多个服务器。客户端主机是指希望通过 MCP 访问数据的程序,比如 Claude Desktop、IDE 或 AI 工具。
我们可以使用 Spring AI 框架来开发 MCP 服务,可以先通过 官方文档 来了解其基本架构。
遵循三层架构:
我们分别来看每一层的作用:
客户端/服务器层:McpClient 处理客户端操作,而 McpServer 管理服务器端协议操作。两者都使用 McpSession 进行通信管理。会话层(McpSession):通过 DefaultMcpSession 实现管理通信模式和状态。传输层(McpTransport):处理 JSON-RPC 消息序列化和反序列化,支持多种传输实现。MCP 客户端MCP 客户端是 MCP 架构中的关键组件,主要负责和 MCP 服务器建立连接并进行通信。它能自动匹配服务器的协议版本,确认可用功能,并负责数据传输和 JSON-RPC 交互。此外,它还能发现和使用各种工具、管理资源,并与提示系统进行交互。
除了这些核心功能,MCP 客户端还支持一些额外特性,比如根管理、采样控制,以及同步或异步操作。为了适应不同场景,它提供了多种数据传输方式,包括标准输入/输出、基于 Java HttpClient 和 WebFlux 的 SSE 传输。
MCP 服务器是整个 MCP 架构的核心部分,主要用来为客户端提供各种工具、资源和功能支持。它负责处理客户端的请求,包括解析协议、提供工具、管理资源以及处理各种交互信息。同时,它还能记录日志、发送通知,并且支持多个客户端同时连接,保证高效的通信和协作。它可以通过多种方式进行数据传输,比如标准输入/输出、Servlet、WebFlux 和 WebMVC,满足不同应用场景的需求。
可以通过引入一些依赖,直接让 Spring AI 和 MCP 进行集成,在 Spring Boot 项目中轻松使用。
比如客户端启动器:
spring-ai-starter-mcp-client:核心启动器,提供 STDIO 和基于 HTTP 的 SSE 支持spring-ai-starter-mcp-client-webflux:基于 WebFlux 的 SSE 流式传输实现服务器启动器:
spring-ai-starter-mcp-server:核心服务器,具有 STDIO 传输支持spring-ai-starter-mcp-server-webmvc:基于 Spring MVC 的 SSE 流式传输实现spring-ai-starter-mcp-server-webflux:基于 WebFlux 的 SSE 流式传输实现下面我们来实战 MCP 项目的开发。
MCP 的使用分为两种模式,STDIO 模式(本地运行)和 SSE 模式(远程服务)。
基于 stdio 的实现是最常见的 MCP 客户端方案,它通过标准输入输出流与 MCP 服务器进行通信。这种方式简单直观,能够直接通过进程间通信实现数据交互,避免了额外的网络通信开销。特别适用于本地部署的 MCP 服务器,可以在同一台机器上启动 MCP 服务器进程,与客户端无缝对接。
1、引入依赖
org.springframework.ai spring-ai-mcp-server-spring-boot-starter 1.0.0-M62、配置 MCP 服务端
spring:application: name: mcp-servermain: web-application-type: none # 必须禁用web应用类型 banner-mode: off # 禁用bannerai: mcp: server: stdio: true # 启用stdio模式 name: mcp-server # 服务器名称 version: 0.0.1 # 服务器版本3、实现 MCP 工具
@Tool 是 Spring AI MCP 框架中用于快速暴露业务能力为 AI 工具的核心注解,该注解实现 Java 方法与 MCP 协议工具的自动映射,并且可以通过注解的属性 description,帮助人工智能模型根据用户输入的信息决定是否调用这些工具,并返回相应的结果。
下面是一段示例代码:
/*** 根据搜索词搜索面试鸭面试题目** @param searchText 搜索词* @return 面试鸭搜索结果的题目链接*/@Tool(description = "根据搜索词搜索面试鸭面试题目(如果用户提的问题的技术面试题,优先搜索面试鸭的题目列表)")public String callMianshiya(String searchText) { // 执行从面试鸭数据库中搜索题目的逻辑(代码省略) System.out.println("用户要搜索:" + searchText);}4、注册 MCP 工具
最后向 MCP 服务注册刚刚写的工具:
@Beanpublic ToolCallbackProvider serverTools(MianshiyaService mianshiyaService) { return MethodToolCallbackProvider.builder .toolObjects(mianshiyaService) .build;}这段代码定义了一个 Spring 的 Bean,用于将面试鸭的题目搜索服务MianshiyaService中所有用 @Tool 注解标记的方法注册为工具,供 AI 模型调用。ToolCallbackProvider是 Spring AI 中的一个接口,用于定义工具发现机制,主要负责将那些使用 @Tool 注解标记的方法转换为工具回调对象,并提供给 ChatClient 或ChatModel 使用,以便 AI 模型能够在对话过程中调用这些工具。
5、运行服务端
MCP 服务端代码写完之后,直接用 Maven 打包运行项目:
1、引入依赖
org.springframework.ai spring-ai-mcp-client-spring-boot-starter 1.0.0-M62、配置 MCP 服务器
因为刚刚服务端是通过stdio实现的,需要在application.yml中配置MCP服务器的一些参数:
spring:ai: mcp: client: stdio: # 指定MCP服务器配置文件 servers-configuration: classpath:/mcp-servers-config.jsonmandatory-file-encoding: UTF-8其中 mcp-servers-config.json 的配置如下:
{ "mcpServers": { "mianshiyaServer": { "command": "java", "args": [ "-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none", "-Dlogging.pattern.console=", "-jar", "/Users/yupi/Documents/mcp-server/target/mcp-server-0.0.1-SNAPSHOT.jar" ], "env": {} }}}这个配置文件设置了 MCP 客户端的基本配置,包括 Java 命令参数,服务端 jar 包的绝对路径等。上述的 JSON 配置文件也可以直接写在application.yml里,效果是一样的。
mcp: client: stdio: connections: server1: command: java args: - -Dspring.ai.mcp.server.stdio=true - -Dspring.main.web-application-type=none - -Dlogging.pattern.console= - -jar - /Users/yupi/Documents/mcp-server/target/mcp-server-0.0.1-SNAPSHOT.jar客户端我们使用阿里巴巴的通义千问模型,所以引入 spring-ai-alibaba-starter 依赖,如果你使用的是其他的模型,也可以使用对应的依赖项,比如 openAI 引入 spring-ai-openai-spring-boot-starter 这个依赖就行了。还需要配置大模型的密钥等信息,key 可以直接 去官网 申请,模型我们用的是 qwen-max。
spring:ai: dashscope: api-key: ${通义千问的key} chat: options: model: qwen-max3、初始化聊天客户端,一行代码就搞定了:
@Beanpublic ChatClient initChatClient(ChatClient.Builder chatClientBuilder, ToolCallbackProvider mcpTools) { return chatClientBuilder.defaultTools(mcpTools).build;}这段代码定义了一个 Spring Bean,用于初始化一个AI 聊天客户端,里面有两个参数:
ChatClient.Builder 是 Spring AI 提供的 AI 聊天客户端构建器,用于构建 ChatClient 实例,是由 Spring AI自动注入的另一个是 ToolCallbackProvider,用于从 MCP 服务端发现并获取 AI 工具。4、接口调用
直接调用ChatClient,将面试问题输入给AI即可,也不需要写过多的 prompt,因为在 MCP 服务端的工具描述中,已经写的比较详细了 —— 比如用户想要搜索技术面试题,就会自动调用刚刚写的工具。
普通调用:
@PostMapping(value = "/ai/answer")public String generate(@RequestBody AskRequest request) { return chatClient.prompt .user(request.getContent) .call .content;}如果需要实时输出返回内容,可以进行 SSE 流式调用:
@PostMapping(value = "/ai/answer/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux generateStreamAsString(@RequestBody AskRequest request) { Flux content = chatClient.prompt .user(request.getContent) .stream .content; return content .concatWith(Flux.just("[complete]"));}最后测试一下,输入面试题目 “HashMap的原理是啥”,就会返回 面试鸭 的题目以及链接。
除了基于 stdio 的实现外,Spring AI 还提供了基于 Server-Sent Events (SSE) 的 MCP 客户端方案。相较于 stdio 方式,SSE 更适用于远程部署的 MCP 服务器,客户端可以通过标准 HTTP 协议与服务器建立连接,实现单向的实时数据推送。基于 SSE 的 MCP 服务器支持被多个客户端远程调用。
1、引入依赖
org.springframework.ai spring-ai-mcp-server-webflux-spring-boot-starter 1.0.0-M62、配置 MCP 服务端
server:port: 8090spring:application: name: mcp-serverai: mcp: server: name: mcp-server # MCP服务器名称 version: 0.0.1 # 服务器版本号除了引入的依赖包不一样,以及配置文件不同,其他的不需要修改。
3、运行服务端
MCP 服务端写完之后,直接打包运行:
mvn clean package -DskipTests直接用 jar 选项运行 MCP 服务端:
java -jar target/mcp-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod1、引入依赖
org.springframework.ai spring-ai-mcp-client-webflux-spring-boot-starter 1.0.0-M62、配置 MCP 服务器
因为刚刚服务端是通过 SSE 实现的,需要在application.yml中配置 MCP 服务器的 URL 端口:
spring:ai: mcp: client: enabled: true name: mcp-client version: 1.0.0 request-timeout: 30s type: ASYNC # 类型同步或者异步 sse: connections: server1: url: http://localhost:8090和 MCP 服务端的修改一样, 除了依赖和配置的修改,其他的也不需要调整。
最后测试一下,输入面试题目 “MySQL的事务是怎么实现的?”,就会返回 面试鸭 的题目以及链接等。
除了利用程序去调用 MCP 服务外,MCP 服务端还任意支持 MCP 协议的智能体助手,比如 Claude、Cursor 以及 Cherry Studio 等,都可以快速接入。(前提需要 Java 运行时环境)
首先下载我们 开源的面试鸭 MCP 服务 代码到本地:
git clone https://github.com/yuyuanweb/mcp-mianshiya-server然后使用 Maven 打包构建项目:
下面我们以 Cherry Studio 这样一个 AI 客户端软件为例,演示如何使用 MCP 服务。
1、打开 Cherry Studio 的 “设置”,点击 “MCP 服务器”:
2、点击 “编辑 JSON”,将以下 MCP 配置添加到配置文件中:
{ "mcpServers": { "mianshiyaServer": { "command": "java", "args": [ "-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none", "-Dlogging.pattern.console=", "-jar", "/yourPath/mcp-server-0.0.1-SNAPSHOT.jar" ], "env": {} }}}3、在 “设置 => 模型服务” 里选择一个模型,输入 API 密钥,选择模型设置,勾选下工具函数调用功能:
4、进入聊天页面,在输入框下面勾选开启 MCP 服务:
配置完成,尝试搜索下面试题目,效果不戳!
甚至还进行面经解析,返回多个面试题目与答案的链接!
当然这个功能我们面试鸭官方也实现了,帮助大家面试复盘:
和开发一个 APP 一样,我们也可以把做好的 MCP 服务分享到第三方 MCP 服务平台。比如 MCP.so,可以理解为 MCP 服务的应用市场。
直接点击头像左侧的提交按钮,然后填写 MCP 服务的项目地址、以及服务器配置实例,点击提交即可。
提交完成后就可以在平台搜索到了:
OK 就分享到这里,学会的话记得点赞收藏哦。也欢迎大家在评论区交流你对 MCP 的看法和理解~
来源:程序员鱼皮