MCP核心知识
什么是MCP
- 核心定义 :由 Anthropic 于 2024 年 11 月推出的开放标准协议,被称为 "AI 领域的 USB-C 接口",旨在标准化大语言模型 (LLM) 与外部工具、数据源的连接方式
- 核心功能 :
- 提供统一接口,解决传统工具调用中接口混乱、上下文管理复杂问题
- 支持模型实时调用外部资源(数据库、API、文件系统等),实现决策层与执行层解耦
- 通过 JSON-RPC 2.0 规范通信,维护会话状态和多轮交互数据
- 应用场景:AI 智能体开发、RAG 系统、工具调用、知识库管理等
MCP 架构
1、宏观架构
MCP 的核心是 "客户端 - 服务器" 架构,其中 MCP 客户端主机可以连接到多个服务器。客户端主机是指希望访问 MCP 服务的程序,比如 Claude Desktop、IDE、AI 工具或部署在服务器上的项目。
2、SDK 3 层架构
如果我们要在程序中使用 MCP 或开发 MCP 服务,可以引入 MCP 官方的 SDK,比如 Java SDK。让我们先通过 MCP 官方文档了解 MCP SDK 的架构,主要分为 3 层:
分别来看每一层的作用:
- 客户端 / 服务器层:McpClient 处理客户端操作,而 McpServer 管理服务器端协议操作。两者都使用 McpSession 进行通信管理。
- 会话层(McpSession):通过 DefaultMcpSession 实现管理通信模式和状态。
- 传输层(McpTransport):处理 JSON-RPC 消息序列化和反序列化,支持多种传输实现,比如 Stdio 标准 IO 流传输和 HTTP SSE 远程传输。
MCP 核心概念
很多人以为 MCP 协议就只能提供工具给别人调用,但实际上,MCP 协议的本领可大着呢!
按照官方的说法,总共有 6 大核心概念。大家简单了解一下即可,除了 Tools 工具之外的其他概念都不是很实用,如果要进一步学习可以阅读对应的官方文档。
- Resources 资源:让服务端向客户端提供各种数据,比如文本、文件、数据库记录、API 响应等,客户端可以决定什么时候使用这些资源。使 AI 能够访问最新信息和外部知识,为模型提供更丰富的上下文。
- Prompts 提示词:服务端可以定义可复用的提示词模板和工作流,供客户端和用户直接使用。它的作用是标准化常见的 AI 交互模式,比如能作为 UI 元素(如斜杠命令、快捷操作)呈现给用户,从而简化用户与 LLM 的交互过程。
- Tools 工具:MCP 中最实用的特性,服务端可以提供给客户端可调用的函数,使 AI 模型能够执行计算、查询信息或者和外部系统交互,极大扩展了 AI 的能力范围。
- Sampling 采样:允许服务端通过客户端向大模型发送生成内容的请求(反向请求)。使 MCP 服务能够实现复杂的智能代理行为,同时保持用户对整个过程的控制和数据隐私保护。
- Roots 根目录:MCP 协议的安全机制,定义了服务器可以访问的文件系统位置,限制访问范围,为 MCP 服务提供安全边界,防止恶意文件访问。
- Transports 传输:定义客户端和服务器间的通信方式,包括 Stdio(本地进程间通信)和 SSE(网络实时通信),确保不同环境下的可靠信息交换。
如果要开发 MCP 服务,我们主要关注前 3 个概念,当然,Tools 工具是重中之重!
使用 MCP
本节我们将实战 3 种使用 MCP 的方式:
- 云平台使用 MCP
- 软件客户端使用 MCP
- 程序中使用 MCP
无论是哪种使用方式,原理都是类似的,而且有 2 种可选的使用模式:本地下载 MCP 服务端代码并运行 (类似引入了一个 SDK),或者 直接使用已部署的 MCP 服务(类似调用了别人的 API)。
MCP 服务大全
目前已经有很多 MCP 服务市场,开发者可以在这些平台上找到各种现成的 MCP 服务:
- MCP.so:较为主流,提供丰富的 MCP 服务目录
- GitHub Awesome MCP Servers:开源 MCP 服务集合
- 阿里云百炼 MCP 服务市场
- Spring AI Alibaba 的 MCP 服务市场
- Glama.ai MCP 服务
云平台使用 MCP
以阿里云百炼为例,参考 官方 MCP 文档,我们可以直接使用官方预置的 MCP 服务,或者部署自己的 MCP 服务到阿里云平台上。
如图,官方提供了很多现成的 MCP 服务:
让我们进入一个智能体应用,在左侧可以点击添加 MCP 服务,然后选择想要使用的 MCP 服务即可,比如使用高德地图 MCP 服务,提供地理信息查询等 12 个工具。
申请高德开放平台KEY
由于高德地图的API也不是免费调用的,想要使用它的服务,需要申请高德开放平台的KEY
进入官方网址:高德开放平台 | 高德地图API

按照步骤进行注册,过程比较简单不过多赘述,登录成功后进入控制台
输入应用名称和类型即可如图
创建成功后,在应用列表中找到此引用,点击后面的添加[KEY]链接
弹出添加key对话框中,填写key名称,并选择[web服务],勾选同意协议确认即可

最后复制创建的Key

百炼平台使用高德MCP
有了key我们就可以在阿里云百炼平台进行调用了
1.开通高德MCP服务
登录阿里云百炼平台,选择MCP选项,找到Amap Maps 这个是高德的MCP服务
进入开通页面点击立即开通按钮,填入之前创建的key
2.将MCP服务添加到AI应用
找到 旅游大师应用 没看过的可以看前面几章文章
点击配置,进来之后选择mcp右侧有个 + 选择已经开通的MCP
提出与地理位置相关的问题,就可以看到MCP的调用了,注意不能使用deepseek-v3.1这类纯文本模型他是不支持MCP的
旅游大师集成高德地图MCP
我们回到项目中,如何在Spring AI框架下集成MCP服务呢?下面我们就如何将高德地图MCP集成到我们"旅游大师"应用中
首先了解 Spring AI MCP 客户端的基本使用方法。建议参考 Spring AI Alibaba 的文档,因为 Spring AI 官方文档 更新的太快了,包的路径可能会变动。
引入依赖:
XML
<!-- 添加Spring AI MCP starter依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
配置mcp-servers-config.json
在 resources 目录下新建 mcp-servers.json 配置,定义需要用到的 MCP 服务:
java
{
"mcpServers": {
"amap-maps": {
"command": "npx",
"args": [
"-y",
"@amap/amap-maps-mcp-server"
],
"env": {
"AMAP_MAPS_API_KEY": "改成你的 API Key"
}
}
}
}
修改 Spring 配置文件,编写 MCP 客户端配置。由于是本地运行 MCP 服务,所以使用 stdio 模式,并且要指定 MCP 服务配置文件的位置。代码如下:
java
spring:
ai:
mcp:
client:
stdio:
servers-configuration: classpath:/mcp-server-config-dev.json
为TravelApp添加MCP
修改TravelApp
通过自动注入的ToolCallbackProvider获取到配置中定义的MCP服务提供的所有工具,并提供给ChatClient
修改TravelApp

当我们配置了MCP服务,在程序启动时,Spring会自动注入McpClient和ToolCallbackProvider,此时会向MCP Server段发送请求获取所有可以用的工具列表
测试MCP功能
java
@Test
void testMCP(){
String chatId = UUID.randomUUID().toString();
String result = travelApp.chat(chatId,"帮我查一下郴州高椅岭附近5公里的酒店");
System.out.println(result);
}
在windows环境下运行,会出现找不到npx命令的错误,解决方法很简单,把正确的npx改成npx.cmd即可
我们再次运行会出现一个ToolContext不支持的问题,因为我们传递了toolContext数据,到这里call(String,ToolContext)这个方法,而ToolCallback默认不支持ToolContext直接抛出异常
那么我们先把这个参数注释,暂时测试一下MCP是否可以调用成功

再次运行就可以正常使用了
解决MCP工具不支持ToolContext问题
通过代理拦截call调用
既然是方法调用的问题,那就可以通过代理模式来处理,通过代理类拦截call的调用,如果是MCP类型的ToolCallback对象,直接调用无toolContext参数的call方法
编写代理类
新建一个mcp包,新建McpToolCallbackProxy代理类:
java
public class McpToolCallbackProxy implements InvocationHandler {
private final FunctionCallback target;
public McpToolCallbackProxy(FunctionCallback target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 拦截MCP工具回调
if(target.getClass().getSimpleName().toLowerCase().contains("mcp")
&& method.getName().equals("call")
&& args.length == 2
&& args[1].getClass().equals(ToolContext.class)){
return target.call(args[0].toString());
}
return method.invoke(proxy, method, args);
}
public static FunctionCallback[] proxyAll(FunctionCallback... callbacks){
FunctionCallback[] proxyArray = new FunctionCallback[callbacks.length];
for(int i = 0; i < callbacks.length; i++){
FunctionCallback callback = callbacks[i];
// 创建代理
proxyArray[i] = (FunctionCallback) Proxy.newProxyInstance(
callback.getClass().getClassLoader(),
callback.getClass().getInterfaces(),
new McpToolCallbackProxy(callback)
);
}
return proxyArray;
}
}
修改App类: