京东自营 618 + 国补 iPhone 历史最低价

使用 Spring AI 实现 MCP 服务并与 Qwen 集成使用

一、MCP介绍

MCP(Model Context Protocol,模型上下文协议)是一种开放协议,旨在实现 大型语言模型(LLM) 应用与外部数据源、工具和服务之间的无缝集成,类似于网络中的 HTTP 协议或邮件中的 SMTP 协议。
MCP 协议通过标准化模型与外部资源的交互方式,提升 LLM 应用的功能性、灵活性和可扩展性。

MCP 的架构由四个关键部分组成:

  • 1、主机(Host):主机是期望从服务器获取数据的人工智能应用,例如一个集成开发环境(IDE)、聊天机器人等。主机负责初始化和管理客户端、处理用户授权、管理上下文聚合等。
  • 2、客户端(Client):客户端是主机与服务器之间的桥梁。它与服务器保持一对一的连接,负责消息路由、能力管理、协议协商和订阅管理等。客户端确保主机和服务器之间的通信清晰、安全且高效。
  • 3、服务器(Server):服务器是提供外部数据和工具的组件。它通过工具、资源和提示模板为大型语言模型提供额外的上下文和功能。例如,一个服务器可以提供与Gmail、Slack等外部服务的API调用。
  • 4、基础协议(Base Protocol):基础协议定义了主机、客户端和服务器之间如何通信。它包括消息格式、生命周期管理和传输机制等。

MCP 关键特性

  • 1、标准化接口:定义统一的接口和协议,确保 LLM 与外部资源的兼容性。
  • 2、动态集成:支持 LLM 动态访问和集成外部数据源和工具。
  • 3、上下文感知:支持动态管理对话上下文,提升多轮对话的连贯性。
  • 4、开放性和可扩展性:支持第三方开发者为 LLM 应用扩展功能和资源。

MCP 与 Function Calling 的区别:

特性MCPFunction Calling
性质协议功能
范围通用(多数据源、多功能)特定场景(单一数据源和功能)
目标统一接口,实现互操作扩展模型能力
实现基于标准协议(JSON-RPC 2.0,标准请求、响应和通知消息)依赖于特定模型实现
通信机制MCP 支持多种传输机制,包括本地的标准输入/输出(Stdio)和基于HTTP的服务器发送事件(SSE)。Function Calling 使用 HTTP 作为通信机制。
开发复杂度低:通过统一协议实现多源兼容高:需要为每个任务单独开发函数
复杂性高:一次开发,可多场景使用低:函数通常为特定任务设计
灵活性高:支持动态适配和扩展低:功能扩展需要额外开发
常见场景复杂场景,如跨平台数据访问与整合简单任务,如天气查询、翻译等
整合难度一次标准化整合每个API单独整合
实时双向通讯支持不支持
动态发现工具支持不支持


二、SpringAI MCP 介绍

Spring AI MCP,它是模型上下文协议(Model Context Protocol,MCP)的 Java SDK 实现。Spring AI 生态系统的这一新成员为 Java 平台带来了标准化的 AI 模型集成能力。

MCP 的核心是客户端-服务器(CS)架构,一个应用可以连接多个服务器。

Spring AI MCP 采用模块化架构,包含以下组件:

  • 1、Spring AI 应用: 使用 Spring AI 框架构建希望通过 MCP 访问数据的生成式 AI 应用。
  • 2、Spring MCP 客户端:与服务器保持 1:1 连接的 MCP 协议的 Spring AI 实现。
  • 3、Spring MCP 服务器:轻量级程序,每个程序都通过标准化的模型上下文协议公开特定功能。
  • 4、本地数据源:MCP 服务器可安全访问的计算机文件、数据库和服务。
  • 5、远程服务:MCP 服务器可通过互联网(如 API)连接的外部系统。


三、使用 SpringAI 开发 MCP 服务

第一步:引入 spring-ai 依赖

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

第二步:开发 MCP Tool,并注册暴露 MCP Server

// 开发 MCP Tool
@Service
public class WeatherService {
    @Tool(description = "根据城市名称获取天气预报")
    public String getWeatherByCity(@ToolParam(description = "城市名称") String city) {
        if (Objects.isNull(city)) {
            return "抱歉:城市名称不能为空!";
        }
        // 模拟天气数据
        Map<String, String> mockData = Map.of(
                "西安", "晴天",
                "北京", "小雨",
                "上海", "大雨"
        );
        return mockData.getOrDefault(city, "抱歉:未查询到对应城市!");
    }
}
// 注册暴露 MCP Server
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
    return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}


第三步:自测验证(SSE方式)

  • 启动 MCP 服务(SSE方式需要手动启动)
public static void main(String[] args) {
    SpringApplication.run(ServerApplication.class, args);
}
  • 发起 SSE 请求
// 初始化 SSE Client
var client = McpClient.sync(new HttpClientSseClientTransport("http://localhost:8080")).build(
// 发起请求
CallToolResult getWeatherByCity = client.callTool(new CallToolRequest("getWeatherByCity", Map.of("city", "上海")));
System.out.println("上海天气是:" + getWeatherByCity);

第四步:自测验证(STDIO方式)

// 初始化 STDIO Client
var stdioParams = ServerParameters.builder("java")
        .args("-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none",
                "-Dlogging.pattern.console=", "-jar",
                "/Users/admin/program/git-space/project/abc-demo/spring-ai-mcp/mcp-server/target/mcp-server-1.0.0-SNAPSHOT.jar")
        .build();
var client = McpClient.sync(new StdioClientTransport(stdioParams)).build(
// 发起请求
CallToolResult getWeatherByCity = client.callTool(new CallToolRequest("getWeatherByCity", Map.of("city", "上海")));
System.out.println("上海天气是:" + getWeatherByCity);

第五步:查看日志输出

// MCP服务 Tools列表:
Available Tools = ListToolsResult[tools=[Tool[name=getWeatherByCity, description=根据城市名称获取天气预报, inputSchema=JsonSchema[type=object, properties={arg0={type=string, description=城市名称}}, required=[arg0], additionalProperties=false]]], nextCursor=null]
// MCP服务 天气查询结果:
上海 天气为:CallToolResult[content=[TextContent[audience=null, priority=null, text="小雨"]], isError=false]


四、Qwen 集成 MCP 服务

当前,大型语言模型(LLM)并非普遍支持模型上下文协议(MCP),本文选择已支持MCP的 Qwen2.5 模型基座,使用 Cherry Studio 作为模型工具。

另外,由于上文示例过于简单,为确保演示效果从 glama.ai(已收集1K+MCP服务)选择2个开源 MCP服务进行集成演示。

  • 1、mcp-trends-hub:该MCP服务,支持获取各种格式的web内容,包括HTML、JSON、纯文本和Markdown等。
展开阅读全文

本文系作者在时代Java发表,未经许可,不得转载。

如有侵权,请联系nowjava@qq.com删除。

编辑于

关注时代Java

关注时代Java