搞AI开发的时候,不知道你有没有遇到过这种场景:
一开始用OpenAI写了个查订单的Function Calling,跑得挺好。半年后老板说要换成通义千问,结果发现参数格式全变了,所有工具都得重写一遍。
再过一阵子,业务方说想给AI加个文件系统访问能力,又得从头开发一遍。开发群里天天问:能不能一套工具适配所有模型?
我最近在项目中接触到的一个东西,恰好能解决这个问题------MCP(Model Context Protocol) 。简单说,它就是AI领域的"USB-C接口"。

📌 MCP到底是什么?AI界的"万能插座"
如果你接触过Function Calling,会知道它的运行方式是:你要先定义好几个工具函数,调用AI模型时,把这些工具声明一起发过去,模型判断该用哪个。
但这有个很头疼的限制------工具是静态的 。每次要新增能力,都得改代码、重新部署,不能动态增减。
MCP就是来解决这个问题的。它是一种标准化协议 ,让AI模型和外部工具之间用统一的规范来通信。把MCP想象成USB-C接口------不管你插的是U盘还是硬盘,接口都一样。用了MCP之后,不管用什么AI模型,接入一套MCP Server,模型就能自动发现并使用这些能力。

🛠️ 用Spring Boot + MCP接工具,到底有多省事儿?
直接上代码。目标很简单:让AI能访问公司内部Git仓库,问"帮我看看最近一周有哪些代码提交",AI自动调用工具,返回结果。
第一步:添加依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>1.1.2.0</version>
</dependency>
<!-- MCP Client自动配置包 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
第二步:告诉AI要去哪里接工具
在 application.yml 里加一段配置,让应用知道从哪里找MCP服务:
yaml
spring:
ai:
mcp:
client:
toolcallback:
enabled: true
stdio:
servers-configuration: classpath:/mcp-server.json5
然后在 src/main/resources 下创建 mcp-server.json5:
json
{
"mcpServers": {
"company-git": {
"command": "npx",
"args": ["-y", "@mycompany/git-mcp-server"],
"env": {
"GIT_API_TOKEN": "${MY_GIT_TOKEN}"
}
}
}
}
这段文件的作用很简单:告诉MCP Client,有个 company-git 服务,用 npx 启动它,运行时注入Git的Token。

第三步:配置ChatClient
java
@Configuration
public class AiConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel,
ToolCallbackProvider toolCallbackProvider) {
return ChatClient.builder(chatModel)
.defaultSystem("你是公司内部的智能助理。")
.defaultTools(toolCallbackProvider)
.build();
}
}
第四步:写个Controller测试
java
@RestController
public class ChatController {
@Autowired
private ChatClient chatClient;
@PostMapping("/chat")
public String chat(@RequestBody String userMessage) {
return chatClient.prompt()
.user(userMessage)
.call()
.content();
}
}
然后向接口发一个请求:
text
POST /chat
{
"userMessage": "帮我查一下最近一周有哪些代码提交"
}
AI会自己判断要调用Git MCP Server里的工具,从仓库里拉出提交记录,再把结果整理成你能看懂的人话。
整个过程里,一行工具实现的代码都没写。所有能力都来自MCP Server的自动发现和注册。
🤔 MCP比Function Calling多了什么?
两者不是二选一的关系,它们在AI工具调用的链路中干的是不同的事。
| 角度 | Function Calling | MCP |
|---|---|---|
| 做什么的 | 模型自己决定调用哪个工具 | 模型和工具之间对话的"翻译官" |
| 工具怎么来 | 代码里硬编码工具声明 | 独立服务动态提供,工具增减无需改应用代码 |
| 一个模型一套工具吗 | 对,换个模型可能要重写 | 模型和工具完全解耦,一套MCP Server服务于任何支持MCP的模型 |
有人形象地总结过:FC是AI的"决策层",负责选工具、生成参数;MCP是后端与工具间的"执行协议",统一调用标准。在一个完整的AI Agent架构里,两者可以配合使用,不冲突。
💡 实际开发中的几个坑
1. 启动MCP Server的命令路径
mcp-server.json5 里的 command 字段,如果填 npx 或 python,MCP Client会用它尝试启动子进程。但如果运行Spring Boot的环境里没有全局安装这些命令,就会启动失败。Java开发者普遍更熟悉JVM环境,跨语言启动Python/Node服务时,建议在部署前检查目标环境是否包含所需运行时,或者把MCP Server打成独立可执行文件再配置 command 路径。
2. 环境变量别写死
Token、密钥这类敏感信息,一定要用 "${ENV_NAME}" 的写法传进去,千万不要明文写在配置文件里提交到代码仓库。
3. 超时配置很关键
有的MCP Server执行耗时比较长。可以在 application.yml 里配置合适的 request-timeout:
yaml
spring:
ai:
mcp:
client:
request-timeout: 30s

📌 实战中怎么选:什么时候上MCP,什么时候用FC?
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 工具不多、业务边界清晰,团队对当前模型调用稳定满意 | Function Calling | 实现简单直接,没有额外的运维负担 |
| 预期工具会持续扩展(如接入第三方API服务、内部多个业务系统),或者准备对接多个大模型厂商 | MCP | 一次接入,处处可用 |
两者的关系更像互补而非互相替代。有数据统计,目前63%的企业级AI Agent采用混合架构,核心业务上继续用Function Calling保证性能,创新业务上通过MCP快速探索接入新工具。
这次我们聊的是MCP Client接入已有工具 ,也就是AI应用怎么"消费"别人写好的MCP服务。下一期可以考虑聊聊MCP Server,即如何把业务系统里的接口包装成MCP标准服务,给更多AI应用复用。