AI智能体开发技术调研总结 - 自定义 MCP 服务
Model Context Protocol (MCP) 是一个标准化协议,使 AI 模型能够以结构化的方式与外部工具和资源交互。 可以将其视为 AI 模型与现实世界之间的桥梁——允许它们通过一致的接口访问数据库、API、文件系统和其他外部服务。 它支持多种传输机制,以在不同环境中提供灵活性。
MCP Java SDK 提供了 Model Context Protocol 的 Java 实现,通过同步和异步通信模式实现与 AI 模型和工具的标准化交互。
Spring AI 通过专用的 Boot Starters 和 MCP Java Annotations 全面支持 MCP,使构建能够无缝连接到外部系统的复杂 AI 驱动应用程序变得前所未有的简单。 这意味着 Spring 开发者可以参与 MCP 生态系统的两个方面——构建消费 MCP 服务器的 AI 应用程序,以及创建将基于 Spring 的服务暴露给更广泛 AI 社区的 MCP 服务器。 使用 Spring Initializer 引导支持 MCP 的 AI 应用程序。
相关链接:
1、【Spring ai alibaba官方文档】Model Context Protocol(MCP)概览 | Spring AI Alibaba
https://java2ai.com/integration/mcps/examples/mcp
2、本文中的源码
本文中的工程源码已开源至Gitee代码仓库,地址为:
3、AI智能体开发技术调研总结系列文章:
一、自定义 MCP 服务
1、pom.xml
<dependencyManagement>
<dependencies>
<!-- Spring AI BOM 统一管理版本 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring AI MCP Server -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
</dependencies>
2、application.yml
在配置文件中定义了 MCP 服务名、MCP 传输协议、MCP API地址,所以客户端调用该 MCP 服务地址是 http://localhost:8081/api/mcp/streamable
spring:
application:
name: mcpserver
ai:
mcp:
server:
# MCP 服务名
name: tyzwkj-customMcp
version: 1.0.0
# 传输协议:STREAMABLE(推荐)| SSE(旧版)| STATELESS(无状态)
protocol: STREAMABLE
# 服务器类型:SYNC(同步,注册同步 @Tool 方法)| ASYNC(异步,注册异步 @Tool 方法)
type: SYNC
# 扫描 @McpTool 注解的 Spring Bean 并自动注册
annotation-scanner:
enabled: true
request-timeout: 20s
streamable-http:
mcp-endpoint: /api/mcp/streamable
keep-alive-interval: 30s
disallow-delete: false
server:
port: 8081
3、定义MCP工具类
通过@Component将该类注入Spring容器中,通过@McpTool声明一个可被模型调用的工具
package cn.tyzwkj.ai.mcpserver.tools;
import org.springaicommunity.mcp.annotation.McpTool;
import org.springaicommunity.mcp.annotation.McpToolParam;
import org.springframework.stereotype.Component;
@Component
public class CalculatorTools {
@McpTool(name = "mcp_calculate_add",
description = "将两个数字相加,返回它们的和。支持整数和小数。")
public double calculateAdd(
@McpToolParam(description = "第一个加数") double a,
@McpToolParam(description = "第二个加数") double b) {
return a + b;
}
@McpTool(name = "mcp_calculate_divide",
description = "用第一个数字除以第二个数字,返回商。除数不能为 0,否则返回错误。支持整数和小数。")
public double calculateDivide(
@McpToolParam(description = "被除数") double a,
@McpToolParam(description = "除数,不能为 0") double b) {
if (b == 0) {
throw new IllegalArgumentException("除数不能为 0,请传入非零的除数。");
}
return a / b;
}
@McpTool(name = "mcp_calculate_power",
description = "计算 base 的 exponent 次幂,返回结果。支持小数次幂。")
public double calculatePower(
@McpToolParam(description = "底数") double base,
@McpToolParam(description = "指数") double exponent) {
return Math.pow(base, exponent);
}
@McpTool(name = "mcp_calculate_square_root",
description = "计算一个非负数的平方根,返回结果。负数没有实数平方根,会返回错误。")
public double calculateSquareRoot(
@McpToolParam(description = "开方数,必须为非负数") double x) {
if (x < 0) {
throw new IllegalArgumentException("负数没有实数平方根,参数 x=" + x + " 必须 >= 0。");
}
return Math.sqrt(x);
}
}
4、MCP 服务认证
通过引入认证过滤器,只对存在请求头 token-1,且只为 tyzwkjmcp-1 的连接放行
package cn.tyzwkj.ai.mcpserver.filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.List;
/**
* Mcp 服务认证过滤器,实现 WebFilter
* 只对存在请求头 token-1,且只为 tyzwkjmcp-1 的连接放行。
*/
@Component
public class McpServerAuthFilter extends OncePerRequestFilter {
private static final String TOKENHEADER = "token-1";
private static final String TOKENVALUE = "tyzwkjmcp-1";
/** 需要鉴权的路径(MCP Streamable HTTP 端点),可按需扩展 */
private static final List<String> PROTECTED_PATTERNS = List.of("/api/mcp/**");
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
private static final Logger logger = LoggerFactory.getLogger(McpServerAuthFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String path = request.getRequestURI();
if (!isProtected(path)) {
chain.doFilter(request, response);
return;
}
String token = request.getHeader(TOKENHEADER);
logger.info("鉴权请求: {} {}, TOKEN: {}", request.getMethod(), path, token);
if (TOKENVALUE.equals(token)) {
logger.info("preHandle: 验证通过");
chain.doFilter(request, response);
} else {
logger.warn("Token验证失败: 请求的URL: {}, 提供的TOKEN: {}", path, token);
logger.warn("要求的token为:{}", TOKENVALUE);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
}
}
private boolean isProtected(String path) {
return PROTECTED_PATTERNS.stream().anyMatch(pattern -> PATH_MATCHER.match(pattern, path));
}
}
二、在智能体中集成自定义的 MCP 服务
1、基于AgentScope-java框加构建智能体
详情参见《AI智能体开发技术调研总结》
2、注册MCP服务
示例工程代码如果要展示MCP的效果,需要修改application.yml中的参数agent.mcp.enabled: true,启用MCP
package cn.tyzwkj.ai.agentharness.config;
import cn.tyzwkj.ai.agentharness.tool.BusinessTools;
import cn.tyzwkj.ai.agentharness.tool.KnowledgeTools;
import io.agentscope.core.tool.Toolkit;
import io.agentscope.core.tool.mcp.McpClientBuilder;
import io.agentscope.core.tool.mcp.McpClientWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.Map;
/**
* 工具容器装配。
*
* <p>这里只注册自定义业务工具;Harness 会在此基础上补齐内置工具
* (读写/编辑文件、目录检索、shell 执行、任务清单、记忆检索等),
* 因此不需要手动把内置工具一个个加进来。
*/
@Configuration
public class AgentToolkitConfig {
@Autowired
private AgentProperties agentProperties;
@Bean
public Toolkit agentToolkit(BusinessTools businessTools, KnowledgeTools knowledgeTools) {
Toolkit toolkit = new Toolkit();
toolkit.registerTool(businessTools);
if (agentProperties.getRag().isEnabled()) {
toolkit.registerTool(knowledgeTools);
}
if (agentProperties.getMcp().isEnabled()) {
// 自定义 MCP Server
McpClientWrapper customMcpClient = McpClientBuilder.create("tyzwkj-customMcp")
.streamableHttpTransport("http://localhost:8081/api/mcp/streamable")
.headers(Map.of("token-1", "tyzwkjmcp-1"))
.buildSync();
toolkit.registerMcpClient(customMcpClient).block();
}
return toolkit;
}
}
三、验证
1、启动 MCP 服务

2、启动智能体

3、访问智能体
1、启动成功后在浏览器访问http://localhost:8080,如下图所示画面右侧【已注册工具】中展示出了自定义 MCP 服务的所有工具
2、输入问题 9999+1后,经过推理后智能体决定调用MCP 服务的工具mcp_calculate_add工具

执行结果:


以上就是本次对于智能体开发技术分享的全部内容。
更多推荐

所有评论(0)