langchain4j(四)MCP调用工具
·
一、MCP和function calling 的关系和区别
MCP是在Function Calling基础上的标准化工具调用流程。
Function Calling运行过程:
二、MCP的组成
- MCP Hosts:把你的自定义工具(如天气查询、机票预订、数据库查询)封装成符合 MCP 协议的服务,这个封装后的服务就是 MCP Host。
- MCP Server:MCP Server 是MCP 体系的核心中间件 / 调度中心,是连接MCP Clients和MCP Hosts的 “中转站”,包括工具注册、请求路由与转发,接受请求返回结果等。
- MCP Clients:发起 MCP 协议调用的请求方,就是langchain4j里面封装的大模型
三、客户端通过MCP进行工具调用
- 魔塔的MCP广场,可以找到需要的MCP服务
- 找到对应的json配置

- 在客户端里面加入MCP服务,比如Trae/Cherry Studio/阿里云百炼
- 在VS Code里面下载Cline插件,也可以加入MCP
四、在langchain4j里面使用MCP调用工具
MCP协议规定了两种传输方式:
- HTTP:客户端请求一个SSE(Server-Sent Events)通道以从服务器接收事件,然后通过HTTP POST请求发送命令。这种方式适用于需要跨网络通信的场景,通常用于分布式系统或需要高并发的场景。
- stdio:客户端可以将MCP服务器作为本地子进程运行,并通过标准输入/输出直接与其通信。这种方式适用于本地集成和命令行工具,适合简单的本地批处理任务。
如果需要让ChatModel或AI service运行由MCP服务器提供的工具,则需要创建一个MCP tool provider
引入依赖:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-mcp</artifactId>
<version>0.33.0</version>
</dependency>
1.McpTransport
先要构建一个 MCP 通信方式的实例。
McpTransport transport = new StdioMcpTransport.Builder()
.command(List.of("/usr/bin/npm", "exec", "@modelcontextprotocol/server-everything@0.6.2"))
.logEvents(true) // only if you want to see the traffic in the log
.build();
使用HTTP:
McpTransport transport = new HttpMcpTransport.Builder()
.sseUrl("http://localhost:3001/sse")//SSE 事件channel地址
.logRequests(true) // if you want to see the traffic in the log
.logResponses(true)
.build();
在魔塔上,找到对应的sse地址:

2.创建 MCP 客户端
使用 transport 实例创建 MCP 客户端:
McpClient mcpClient = new DefaultMcpClient.Builder()
.transport(transport)
.build();
3.创建 MCP 工具提供者
ToolProvider toolProvider = McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
4.新建一个MapConfig类,把上面三个写到配置类里面
@Bean
public McpTransport mcpTransport() {
return new HttpMcpTransport.Builder()
.sseUrl("http://localhost:3001/sse")
.logRequests(true)
.logResponses(true)
.build();
}
@Bean
public McpClient mcpClient(McpTransport mcpTransport) {
return new DefaultMcpClient.Builder()
.transport(mcpTransport)
.build();
}
/**
* 👇 这个 Bean 名字非常重要,后面 @AiService 要用
*/
@Bean(name = "mcpToolProvider")
public ToolProvider mcpToolProvider(McpClient mcpClient) {
return McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
}
一个 ToolProvider 只包一个 MCP,所以如果你有多个MCP,就需要创建多个ToolProvider
5.整合本地的@Bean方法调用和MCP
如果有多个工具,需要使用AiServices.builder,所以原来的@AiServices注解就不需要了
public interface ConsultantService {
@SystemMessage(fromResource = "system.txt")
Flux<String> chat(@MemoryId String memoryId,
@UserMessage String message);
}
在MapConfig里面添加ConsultantService的实例
@Configuration
public class McpConfig {
@Autowired
private ReservationTool reservationTool;
@Autowired
private OpenAiChatModel openAiChatModel;
@Autowired
private OpenAiStreamingChatModel openAiStreamingChatModel;
@Autowired
private ContentRetriever contentRetriever;
@Autowired
private ChatMemoryProvider chatMemoryProvider;
@Bean
public McpTransport mcpTransport() {
return new HttpMcpTransport.Builder()
.sseUrl("https://mcp.api-inference.modelscope.net/*/sse")
.logRequests(true)
.logResponses(true)
.build();
}
@Bean
public McpClient mcpClient(McpTransport mcpTransport) {
return new DefaultMcpClient.Builder()
.transport(mcpTransport)
.build();
}
@Bean(name = "mcpToolProvider")
public ToolProvider mcpToolProvider(McpClient mcpClient) {
return McpToolProvider.builder()
.mcpClients(List.of(mcpClient))
.build();
}
@Bean
public ConsultantService consultantService(
ReservationTool reservationTool,
ToolProvider mcpToolProvider
) {
return AiServices.builder(ConsultantService.class)
.chatModel(openAiChatModel)
.streamingChatModel(openAiStreamingChatModel)
.chatMemoryProvider(chatMemoryProvider)
.contentRetriever(contentRetriever)
.tools(reservationTool) // 自定义工具
.toolProvider(mcpToolProvider) // 第一个 MCP
.build();
}
}
然后重新运行我们的项目可以看到,高德地图的功能已经生效:
更多推荐
所有评论(0)