Remove the spring-ai-mcp module from the MCP Java SDK
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
parent
dd64cd88c2
commit
25ad5ed052
6 changed files with 0 additions and 351 deletions
|
|
@ -54,12 +54,6 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Spring AI MCP -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.experimental</groupId>
|
|
||||||
<artifactId>spring-ai-mcp</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
|
||||||
1
pom.xml
1
pom.xml
|
|
@ -107,7 +107,6 @@
|
||||||
<module>mcp</module>
|
<module>mcp</module>
|
||||||
<module>mcp-transport/mcp-webflux-sse-transport</module>
|
<module>mcp-transport/mcp-webflux-sse-transport</module>
|
||||||
<module>mcp-transport/mcp-webmvc-sse-transport</module>
|
<module>mcp-transport/mcp-webmvc-sse-transport</module>
|
||||||
<module>spring-ai-mcp</module>
|
|
||||||
<module>mcp-docs</module>
|
<module>mcp-docs</module>
|
||||||
<module>mcp-test</module>
|
<module>mcp-test</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# Spring AI MCP Spring
|
|
||||||
|
|
||||||
Spring Integration module for Model Control Protocol (MCP) that provides Spring-specific functionality for working with MCP clients.
|
|
||||||
|
|
||||||
Find more at [Java MCP SDK](https://docs.spring.io/spring-ai-mcp/reference/spring-mcp.html)
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.springframework.experimental</groupId>
|
|
||||||
<artifactId>mcp-parent</artifactId>
|
|
||||||
<version>0.7.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>spring-ai-mcp</artifactId>
|
|
||||||
<name>Spring AI MCP</name>
|
|
||||||
<description>Spring Framework integration for Model Context Protocol (MCP), providing Spring AI function calling capabilities and Spring-friendly abstractions for MCP clients and MCP servers</description>
|
|
||||||
<url>https://github.com/spring-projects-experimental/spring-ai-mcp</url>
|
|
||||||
|
|
||||||
<scm>
|
|
||||||
<url>https://github.com/spring-projects-experimental/spring-ai-mcp</url>
|
|
||||||
<connection>git://github.com/spring-projects-experimental/spring-ai-mcp.git</connection>
|
|
||||||
<developerConnection>git@github.com:spring-projects-experimental/spring-ai-mcp.git</developerConnection>
|
|
||||||
</scm>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-core</artifactId>
|
|
||||||
<version>${spring-ai.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-context</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-messaging</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.experimental</groupId>
|
|
||||||
<artifactId>mcp</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-core</artifactId>
|
|
||||||
<version>${springframework.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2024-2024 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.ai.mcp.spring;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.ai.mcp.client.McpSyncClient;
|
|
||||||
import org.springframework.ai.mcp.spec.McpSchema.CallToolRequest;
|
|
||||||
import org.springframework.ai.mcp.spec.McpSchema.CallToolResult;
|
|
||||||
import org.springframework.ai.mcp.spec.McpSchema.Tool;
|
|
||||||
|
|
||||||
import org.springframework.ai.model.ModelOptionsUtils;
|
|
||||||
import org.springframework.ai.model.function.FunctionCallback;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Christian Tzolov
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class McpFunctionCallback implements FunctionCallback {
|
|
||||||
|
|
||||||
// TODO: revisit function calling as well to handle the async case
|
|
||||||
private final McpSyncClient mcpClient;
|
|
||||||
|
|
||||||
private final Tool tool;
|
|
||||||
|
|
||||||
public McpFunctionCallback(McpSyncClient clientSession, Tool tool) {
|
|
||||||
this.mcpClient = clientSession;
|
|
||||||
this.tool = tool;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return this.tool.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return this.tool.description();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getInputTypeSchema() {
|
|
||||||
return ModelOptionsUtils.toJsonString(this.tool.inputSchema());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String call(String functionInput) {
|
|
||||||
Map<String, Object> arguments = ModelOptionsUtils.jsonToMap(functionInput);
|
|
||||||
CallToolResult response = this.mcpClient.callTool(new CallToolRequest(this.getName(), arguments));
|
|
||||||
// Todo handle errors
|
|
||||||
return ModelOptionsUtils.toJsonString(response.content());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,218 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2024 - 2024 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.ai.mcp.spring;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
|
|
||||||
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
|
|
||||||
|
|
||||||
import org.springframework.ai.chat.model.ToolContext;
|
|
||||||
import org.springframework.ai.mcp.server.McpServer;
|
|
||||||
import org.springframework.ai.mcp.server.McpServerFeatures;
|
|
||||||
import org.springframework.ai.mcp.spec.McpSchema;
|
|
||||||
import org.springframework.ai.model.ModelOptionsUtils;
|
|
||||||
import org.springframework.ai.model.function.FunctionCallback;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class that provides helper methods for working with Model Context Protocol
|
|
||||||
* (MCP) tools in a Spring AI environment. This class facilitates the integration between
|
|
||||||
* Spring AI's function callbacks and MCP's tool system.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The MCP tool system enables servers to expose executable functionality to language
|
|
||||||
* models, allowing them to interact with external systems, perform computations, and take
|
|
||||||
* actions in the real world. Each tool is uniquely identified by a name and includes
|
|
||||||
* metadata describing its schema.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This helper class provides methods to:
|
|
||||||
* <ul>
|
|
||||||
* <li>Convert Spring AI's {@link FunctionCallback} instances to MCP tool
|
|
||||||
* registrations</li>
|
|
||||||
* <li>Generate JSON schemas for tool input validation</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @author Christian Tzolov
|
|
||||||
* @see org.springframework.ai.model.function.FunctionCallback
|
|
||||||
* @see org.springframework.ai.mcp.server.McpServer.ToolRegistration
|
|
||||||
* @see org.springframework.ai.mcp.spec.McpSchema.Tool
|
|
||||||
*/
|
|
||||||
public final class ToolHelper {
|
|
||||||
|
|
||||||
private ToolHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<McpServerFeatures.SyncToolRegistration> toSyncToolRegistration(
|
|
||||||
List<FunctionCallback> functionCallbacks) {
|
|
||||||
return functionCallbacks.stream().map(ToolHelper::toSyncToolRegistration).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static List<McpServer.ToolRegistration> toToolRegistration(List<FunctionCallback> functionCallbacks) {
|
|
||||||
return functionCallbacks.stream().map(ToolHelper::toToolRegistration).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<McpServerFeatures.SyncToolRegistration> toSyncToolRegistration(
|
|
||||||
FunctionCallback... functionCallbacks) {
|
|
||||||
return toSyncToolRegistration(List.of(functionCallbacks));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static List<McpServer.ToolRegistration> toToolRegistration(FunctionCallback... functionCallbacks) {
|
|
||||||
return toToolRegistration(List.of(functionCallbacks));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a Spring AI FunctionCallback to an MCP SyncToolRegistration. This enables
|
|
||||||
* Spring AI functions to be exposed as MCP tools that can be discovered and invoked
|
|
||||||
* by language models.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The conversion process:
|
|
||||||
* <ul>
|
|
||||||
* <li>Creates an MCP Tool with the function's name and input schema</li>
|
|
||||||
* <li>Wraps the function's execution in a SyncToolRegistration that handles the MCP
|
|
||||||
* protocol</li>
|
|
||||||
* <li>Provides error handling and result formatting according to MCP
|
|
||||||
* specifications</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* You can use the FunctionCallback builder to create a new instance of
|
|
||||||
* FunctionCallback using either java.util.function.Function or Method reference.
|
|
||||||
* @param functionCallback the Spring AI function callback to convert
|
|
||||||
* @return an MCP SyncToolRegistration that wraps the function callback
|
|
||||||
* @throws RuntimeException if there's an error during the function execution
|
|
||||||
*/
|
|
||||||
public static McpServerFeatures.SyncToolRegistration toSyncToolRegistration(FunctionCallback functionCallback) {
|
|
||||||
var tool = new McpSchema.Tool(functionCallback.getName(), functionCallback.getName(),
|
|
||||||
functionCallback.getInputTypeSchema());
|
|
||||||
|
|
||||||
return new McpServerFeatures.SyncToolRegistration(tool, request -> {
|
|
||||||
try {
|
|
||||||
String callResult = functionCallback.call(ModelOptionsUtils.toJsonString(request));
|
|
||||||
return new McpSchema.CallToolResult(List.of(new McpSchema.TextContent(callResult)), false);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
return new McpSchema.CallToolResult(List.of(new McpSchema.TextContent(e.getMessage())), true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a Spring AI FunctionCallback to an MCP ToolRegistration. This enables
|
|
||||||
* Spring AI functions to be exposed as MCP tools that can be discovered and invoked
|
|
||||||
* by language models.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The conversion process:
|
|
||||||
* <ul>
|
|
||||||
* <li>Creates an MCP Tool with the function's name and input schema</li>
|
|
||||||
* <li>Wraps the function's execution in a ToolRegistration that handles the MCP
|
|
||||||
* protocol</li>
|
|
||||||
* <li>Provides error handling and result formatting according to MCP
|
|
||||||
* specifications</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* You can use the FunctionCallback builder to create a new instance of
|
|
||||||
* FunctionCallback using either java.util.function.Function or Method reference.
|
|
||||||
* @param functionCallback the Spring AI function callback to convert
|
|
||||||
* @return an MCP ToolRegistration that wraps the function callback
|
|
||||||
* @throws RuntimeException if there's an error during the function execution
|
|
||||||
* @deprecated Use {@link #toSyncToolRegistration(FunctionCallback)}.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static McpServer.ToolRegistration toToolRegistration(FunctionCallback functionCallback) {
|
|
||||||
|
|
||||||
var tool = new McpSchema.Tool(functionCallback.getName(), functionCallback.getName(),
|
|
||||||
functionCallback.getInputTypeSchema());
|
|
||||||
|
|
||||||
return new McpServer.ToolRegistration(tool, request -> {
|
|
||||||
try {
|
|
||||||
String callResult = functionCallback.call(ModelOptionsUtils.toJsonString(request));
|
|
||||||
return new McpSchema.CallToolResult(List.of(new McpSchema.TextContent(callResult)), false);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
return new McpSchema.CallToolResult(List.of(new McpSchema.TextContent(e.getMessage())), true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a JSON schema for a map of named classes using the default ObjectMapper.
|
|
||||||
* This schema can be used to validate tool inputs according to the MCP specification.
|
|
||||||
* @param namedClasses a map of class names to their corresponding Class objects
|
|
||||||
* @return a JSON schema string that describes the structure of the named classes
|
|
||||||
* @throws RuntimeException if schema generation fails
|
|
||||||
* @see #generateJsonSchema(Map, ObjectMapper)
|
|
||||||
*/
|
|
||||||
public static String generateJsonSchema(Map<String, Class<?>> namedClasses) {
|
|
||||||
return generateJsonSchema(namedClasses, new ObjectMapper());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a JSON schema for a map of named classes using a custom ObjectMapper. The
|
|
||||||
* generated schema follows the JSON Schema Draft 2020-12 specification and describes
|
|
||||||
* the structure of the provided classes.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This method:
|
|
||||||
* <ul>
|
|
||||||
* <li>Creates a schema that validates the structure of tool inputs</li>
|
|
||||||
* <li>Excludes ToolContext class from schema generation</li>
|
|
||||||
* <li>Uses Jackson's JsonSchemaGenerator for accurate type representation</li>
|
|
||||||
* </ul>
|
|
||||||
* @param namedClasses a map of class names to their corresponding Class objects
|
|
||||||
* @param mapper the ObjectMapper to use for JSON processing
|
|
||||||
* @return a JSON schema string that describes the structure of the named classes
|
|
||||||
* @throws RuntimeException if schema generation fails
|
|
||||||
*/
|
|
||||||
public static String generateJsonSchema(Map<String, Class<?>> namedClasses, ObjectMapper mapper) {
|
|
||||||
try {
|
|
||||||
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
|
|
||||||
|
|
||||||
ObjectNode rootNode = mapper.createObjectNode();
|
|
||||||
rootNode.put("$schema", "https://json-schema.org/draft/2020-12/schema");
|
|
||||||
rootNode.put("type", "object");
|
|
||||||
ObjectNode propertiesNode = rootNode.putObject("properties");
|
|
||||||
|
|
||||||
for (Map.Entry<String, Class<?>> entry : namedClasses.entrySet()) {
|
|
||||||
String className = entry.getKey();
|
|
||||||
Class<?> clazz = entry.getValue();
|
|
||||||
|
|
||||||
if (ClassUtils.isAssignable(clazz, ToolContext.class)) {
|
|
||||||
// Skip the ToolContext class from the schema generation.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonSchema schema = schemaGen.generateSchema(clazz);
|
|
||||||
JsonNode schemaNode = mapper.valueToTree(schema);
|
|
||||||
propertiesNode.set(className, schemaNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue