这个部分我分享一下用Java实现MCP Client的思路。
如何安装可以参考之前的文章《Claude、Cline都在用的MCP协议,正在掀起AI工具新革命》
/**
* 创建一个Fetch MCP Client
*
*@return
*/
publicstaticMcpSyncClientcreateFetchMcpClient(){
// 声明MCP Server的参数
ServerParametersparams=ServerParameters
.builder("node")
.args("/Users/whthomas/Documents/Cline/MCP/fetch-mcp/dist/index.js")
.build();
// 声明MCP Server的传输方式
ClientMcpTransporttransport=newStdioClientTransport(params);
// 创建一个MCP Client
McpSyncClientclient=McpClient
.sync(transport)
.requestTimeout(Duration.ofSeconds(10))
// 设置MCP Client的基本信息
.clientInfo(newMcpSchema.Implementation("Fetch","1.0.0"))
.capabilities(McpSchema.ClientCapabilities.builder().roots(true).sampling().build())
.build();
// 初始化MCP Server
client.initialize();
returnclient;
}publicstaticList<ChatCompletionTool>prepareChatCompletionTools(McpSyncClient mcpClient){
// 列出对应的MCP Server上全部的tools
McpSchema.ListToolsResulttools=mcpClient.listTools();
// 将其转换成OpenAI Client上的Tools参数
returntools
.tools()
.stream()
.map(tool -> {
returnChatCompletionTool
.builder()
.function(FunctionDefinition.builder()
.name(tool.name())
.description(tool.description())
.parameters(prepareFunctionParameters(tool))
.build()
)
.build();
})
.toList();
}
/**
* 将工具的入参定义进行转换
*/
privatestaticFunctionParametersprepareFunctionParameters(Tool tool){
try{
ObjectMapperobjectMapper=newObjectMapper();
StringjsonString=objectMapper.writeValueAsString(tool.inputSchema());
JsonNodejsonNode=objectMapper.readTree(jsonString);
FunctionParameters.BuilderparamsBuilder=FunctionParameters.builder();
jsonNode.fields().forEachRemaining(entry -> {
JsonValuevalue=JsonValue.fromJsonNode(entry.getValue());
paramsBuilder.putAdditionalProperty(entry.getKey(), value);
});
returnparamsBuilder.build();
}catch(JsonProcessingException e) {
thrownewRuntimeException(e);
}
} publicvoidchatWithMcpServer(String userMessage, String chatModel){
List<ChatCompletionTool> chatCompletionTools = McpToolExample.prepareChatCompletionTools(mcpClient);
// 构建ChatCompletionCreateParams对象,设置用户消息、模型、工具等参数
ChatCompletionCreateParamsparams=ChatCompletionCreateParams.builder()
.addUserMessage(userMessage)
.model(chatModel)
.tools(chatCompletionTools)
.build();
// 调用OpenAI的Chat API
openAIClient
.chat()
.completions()
.create(params)
.thenAccept(completion -> completion
.choices()
.stream()
.map(ChatCompletion.Choice::message)
.flatMap(message -> {
message.content().ifPresent(System.out::println);
returnmessage.toolCalls().stream().flatMap(Collection::stream);
})
.forEach(toolCall -> System.out.println(callFunction(toolCall.function())))
)
.join();
}
/**
* 通过MCP Client 调用MCP Server上的方法
*
*@paramfunction LLM思考得到的期望被调用的函数信息(包括函数对应的参数)
*@return
*/
privateStringcallFunction(ChatCompletionMessageToolCall.Function function){
try{
Map<String, Object> toolParams = objectMapper.readValue(function.arguments(), HashMap.class);
McpSchema.CallToolResultresult=mcpClient.callTool(newMcpSchema.CallToolRequest(function.name(), toolParams));
// 将执行的结果返回
returnresult.content().stream().map(Object::toString).collect(Collectors.joining());
}catch(Exception ex) {
returnex.getMessage();
}
}注意:
这几天尝试用Java来编写一个MCP的Client有几个观察:
MCP这个生态目前主流还是以Python和TS为主,但随着企业端的需求逐渐增长(Java应用在企业侧的占比还是非常高的),我认为Java应用在MCP的生态位还是会逐渐变得重要,在生态构建的初期,市场上还是充满了各种竞争的机会。
| 欢迎光临 链载Ai (https://www.lianzai.com/) | Powered by Discuz! X3.5 |