Refactor package structure and dependencies

- Updated package prefix: `org.springframework.ai.mcp` → `org.modelcontextprotocol`
- Changed POM groupId: `org.springframework.experimental` → `org.modelcontextprotocol.sdk`
- Update all dependecies and BOM
- Updated documentation references accordingly

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
Christian Tzolov 2025-01-24 22:08:16 +01:00 • committed by Christian Tzolov
commit 3112e5ede7
8 changed files with 483 additions and 1624 deletions

View file

@ -1,105 +0,0 @@
# Breaking Changes for Spring AI MCP 0.5.0-SNAPSHOT
## Major Changes
1. Transport Implementation Modularization
- SSE transport implementations have been moved to dedicated modules:
- `mcp-webflux-sse-transport`: WebFlux-based SSE transport
- `mcp-webmvc-sse-transport`: WebMVC-based SSE transport
- Base MCP module no longer includes transport implementations
2. Class Renames
- `SseClientTransport` → `WebFluxSseClientTransport`
- `SseServerTransport` → `WebFluxSseServerTransport`
3. Project Structure
- Test utilities moved to new `mcp-test` module
- All samples moved to the the https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol
## Migration Guide
### 1. Update Dependencies
If using SSE transport, add the appropriate transport module to your pom.xml:
For WebFlux SSE transport:
```xml
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>mcp-webflux-sse-transport</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
```
For WebMVC SSE transport:
```xml
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>mcp-webmvc-sse-transport</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
```
### 2. Update Transport Class References
Replace:
```java
import org.springframework.ai.mcp.client.transport.SseClientTransport;
import org.springframework.ai.mcp.server.transport.SseServerTransport;
```
With:
```java
// For WebFlux
import org.springframework.ai.mcp.client.transport.WebFluxSseClientTransport;
import org.springframework.ai.mcp.server.transport.WebFluxSseServerTransport;
// Or for WebMVC
import org.springframework.ai.mcp.server.transport.WebMvcSseServerTransport;
```
### 3. Update Transport Instantiation
Replace:
```java
var transport = new SseClientTransport(webClientBuilder);
```
With:
```java
var transport = new WebFluxSseClientTransport(webClientBuilder);
```
Replace:
```java
var serverTransport = new SseServerTransport(objectMapper, messageEndpoint);
```
With:
```java
// For WebFlux
var serverTransport = new WebFluxSseServerTransport(objectMapper, messageEndpoint);
// Or for WebMVC
var serverTransport = new WebMvcSseServerTransport(objectMapper, messageEndpoint);
```
### 4. Test Dependencies
If you're using MCP test utilities, add the test module dependency:
```xml
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>mcp-test</artifactId>
<version>0.5.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
```
## Other Changes
- Spring AI dependency updated to 1.0.0-M5
- Improved dependency management and reduced transitive dependencies
- Sample application restructured under samples/ directory
- New test utilities and base test classes in mcp-test module

View file

@ -1,239 +0,0 @@
# Spring AI MCP 0.6.0 Migration Guide
This guide outlines the steps required to migrate your code to Spring AI MCP 0.6.0.
## Key Changes
- New builder patterns for `McpClient` and `McpServer`
- Introduction of dedicated feature classes for sync/async operations
- Enhanced type safety and reactive support
- Deprecated methods and classes marked for removal
## Client Migration
### Creating Clients
Before:
```java
// Sync client
McpClient.using(transport)
.requestTimeout(Duration.ofSeconds(5))
.sync();
// Async client
McpClient.using(transport)
.requestTimeout(Duration.ofSeconds(5))
.async();
```
After:
```java
// Sync client
McpClient.sync(transport)
.requestTimeout(Duration.ofSeconds(5))
.build();
// Async client
McpClient.async(transport)
.requestTimeout(Duration.ofSeconds(5))
.build();
```
### Change Consumers
Before:
```java
// Sync client
McpClient.using(transport)
.toolsChangeConsumer(tools -> handleTools(tools))
.resourcesChangeConsumer(resources -> handleResources(resources))
.promptsChangeConsumer(prompts -> handlePrompts(prompts))
.sync();
// Async client
McpClient.using(transport)
.toolsChangeConsumer(tools -> handleTools(tools))
.resourcesChangeConsumer(resources -> handleResources(resources))
.promptsChangeConsumer(prompts -> handlePrompts(prompts))
.async();
```
After:
```java
// Sync client
McpClient.sync(transport)
.toolsChangeConsumer(tools -> handleTools(tools))
.resourcesChangeConsumer(resources -> handleResources(resources))
.promptsChangeConsumer(prompts -> handlePrompts(prompts))
.build();
// Async client
McpClient.async(transport)
.toolsChangeConsumer(tools -> Mono.fromRunnable(() -> handleTools(tools)))
.resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> handleResources(resources)))
.promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> handlePrompts(prompts)))
.build();
```
### Sampling Handlers
Before:
```java
// Sync client
McpClient.using(transport)
.sampling(request -> new CreateMessageResult("response"))
.sync();
// Async client
McpClient.using(transport)
.sampling(request -> new CreateMessageResult("response"))
.async();
```
After:
```java
// Sync client
McpClient.sync(transport)
.sampling(request -> new CreateMessageResult("response"))
.build();
// Async client
McpClient.async(transport)
.sampling(request -> Mono.just(new CreateMessageResult("response")))
.build();
```
## Server Migration
### Creating Servers
Before:
```java
// Sync server
McpServer.using(transport)
.serverInfo("test-server", "1.0.0")
.sync();
// Async server
McpServer.using(transport)
.serverInfo("test-server", "1.0.0")
.async();
```
After:
```java
// Sync server
McpServer.sync(transport)
.serverInfo("test-server", "1.0.0")
.build();
// Async server
McpServer.async(transport)
.serverInfo("test-server", "1.0.0")
.build();
```
### Tool Registration
Before:
```java
// Using ToolRegistration record
new ToolRegistration(
new Tool("calculator", "Performs calculations", schema),
args -> new CallToolResult("result")
);
```
After:
```java
// Sync server
new McpServerFeatures.SyncToolRegistration(
new Tool("calculator", "Performs calculations", schema),
args -> new CallToolResult("result")
);
// Async server
new McpServerFeatures.AsyncToolRegistration(
new Tool("calculator", "Performs calculations", schema),
args -> Mono.just(new CallToolResult("result"))
);
```
### Resource Registration
Before:
```java
// Using ResourceRegistration record
new ResourceRegistration(
new Resource("docs", "Documentation", "text/markdown"),
request -> new ReadResourceResult(content)
);
```
After:
```java
// Sync server
new McpServerFeatures.SyncResourceRegistration(
new Resource("docs", "Documentation", "text/markdown"),
request -> new ReadResourceResult(content)
);
// Async server
new McpServerFeatures.AsyncResourceRegistration(
new Resource("docs", "Documentation", "text/markdown"),
request -> Mono.just(new ReadResourceResult(content))
);
```
### Prompt Registration
Before:
```java
// Using PromptRegistration record
new PromptRegistration(
new Prompt("analyze", "Code analysis"),
request -> new GetPromptResult("result")
);
```
After:
```java
// Sync server
new McpServerFeatures.SyncPromptRegistration(
new Prompt("analyze", "Code analysis"),
request -> new GetPromptResult("result")
);
// Async server
new McpServerFeatures.AsyncPromptRegistration(
new Prompt("analyze", "Code analysis"),
request -> Mono.just(new GetPromptResult("result"))
);
```
## Spring Integration Changes
### Tool Helper Changes
Before:
```java
ToolHelper.toToolRegistration(functionCallback);
ToolHelper.toToolRegistration(functionCallbacks);
```
After:
```java
ToolHelper.toSyncToolRegistration(functionCallback);
ToolHelper.toSyncToolRegistration(functionCallbacks);
```
## Deprecated APIs
The following APIs are deprecated and will be removed in a future release:
- `McpClient.using()` - Use `McpClient.sync()` or `McpClient.async()` instead
- `McpServer.using()` - Use `McpServer.sync()` or `McpServer.async()` instead
- `McpServer.ToolRegistration` - Use `McpServerFeatures.SyncToolRegistration` or `McpServerFeatures.AsyncToolRegistration` instead
- `McpServer.ResourceRegistration` - Use `McpServerFeatures.SyncResourceRegistration` or `McpServerFeatures.AsyncResourceRegistration` instead
- `McpServer.PromptRegistration` - Use `McpServerFeatures.SyncPromptRegistration` or `McpServerFeatures.AsyncPromptRegistration` instead
- `ToolHelper.toToolRegistration()` - Use `ToolHelper.toSyncToolRegistration()` instead

View file

@ -18,7 +18,7 @@
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-parent</artifactId>
<version>0.7.0-SNAPSHOT</version>
</parent>

View file

@ -1,4 +1,3 @@
* xref:overview.adoc[Overview]
** xref:dependency-management.adoc[Dependency Management]
* xref:mcp.adoc[MCP Java SDK]
* xref:spring-mcp.adoc[Spring AI MCP]

View file

@ -20,7 +20,7 @@ Maven::
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-bom</artifactId>
<version>0.6.0-SNAPSHOT</version>
<type>pom</type>
@ -35,7 +35,7 @@ Gradle::
[source,groovy,indent=0,subs="verbatim,quotes"]
----
dependencies {
implementation platform("org.springframework.experimental:mcp-bom:0.6.0-SNAPSHOT")
implementation platform("org.modelcontextprotocol.sdk:mcp-bom:0.6.0-SNAPSHOT")
//...
}
----
@ -53,17 +53,16 @@ The following dependencies are available and managed by the BOM:
=== Core Dependencies
* `org.springframework.experimental:mcp` - Core MCP library providing the base functionality and APIs for Model Context Protocol implementation.
* `org.springframework.experimental:spring-ai-mcp` - Spring AI integration with MCP, providing Spring-specific features and utilities.
* `org.modelcontextprotocol.sdk:mcp` - Core MCP library providing the base functionality and APIs for Model Context Protocol implementation.
=== Transport Dependencies
* `org.springframework.experimental:mcp-webflux-sse-transport` - WebFlux-based Server-Sent Events (SSE) transport implementation for reactive applications.
* `org.springframework.experimental:mcp-webmvc-sse-transport` - WebMVC-based Server-Sent Events (SSE) transport implementation for servlet-based applications.
* `org.modelcontextprotocol.sdk:mcp-webflux-sse-transport` - WebFlux-based Server-Sent Events (SSE) transport implementation for reactive applications.
* `org.modelcontextprotocol.sdk:mcp-webmvc-sse-transport` - WebMVC-based Server-Sent Events (SSE) transport implementation for servlet-based applications.
=== Testing Dependencies
* `org.springframework.experimental:mcp-test` - Testing utilities and support for MCP-based applications.
* `org.modelcontextprotocol.sdk:mcp-test` - Testing utilities and support for MCP-based applications.
[[repositories]]
=== Milestone and Snapshot Repositories

View file

@ -34,7 +34,7 @@ The core MCP functionality:
[source,xml]
----
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
</dependency>
----
@ -46,13 +46,13 @@ For HTTP SSE transport implementations, add one of the following dependencies
----
<!-- Spring WebFlux-based SSE client and server transport -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-webflux-sse-transport</artifactId>
</dependency>
<!-- Spring WebMVC-based SSE server transport -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-webmvc-sse-transport</artifactId>
</dependency>
----
@ -64,7 +64,7 @@ The core MCP functionality:
[source,groovy]
----
dependencies {
implementation 'org.springframework.experimental:mcp'
implementation 'org.modelcontextprotocol.sdk:mcp'
}
----
+
@ -74,10 +74,10 @@ For HTTP SSE transport implementations, add one of the following dependencies
[source,groovy]
----
// Spring WebFlux-based SSE client and server transport
implementation 'org.springframework.experimental:mcp-webflux-sse-transport'
implementation 'org.modelcontextprotocol.sdk:mcp-webflux-sse-transport'
// Spring WebMVC-based SSE server transport
implementation 'org.springframework.experimental:mcp-webmvc-sse-transport'
implementation 'org.modelcontextprotocol.sdk:mcp-webmvc-sse-transport'
----
======
@ -543,7 +543,7 @@ public class McpServerConfig implements WebMvcConfigurer {
}
----
+
(You can implment non Spring web container as well link:https://github.com/spring-projects-experimental/spring-ai-mcp/blob/main/mcp/src/test/java/org/springframework/ai/mcp/server/transport/HttpServletSseServerTransportIntegrationTests.java[HttpServletSseServerTransportIntegrationTests])
(You can implment non Spring web container as well link:https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp/src/test/java/org/springframework/ai/mcp/server/transport/HttpServletSseServerTransportIntegrationTests.java[HttpServletSseServerTransportIntegrationTests])
+
Implements the MCP HTTP with SSE transport specification using the traditional Servlet API, providing:
+

View file

@ -25,20 +25,10 @@ Core implementation of the Model Context Protocol specification, providing:
** Servlet-based SSE server (`HttpServletSseServerTransport`) for HTTP SSE Server streaming using traditional Servlet API
* *Optional SSE Transports*
** link:https://github.com/spring-projects-experimental/spring-ai-mcp/tree/main/mcp-transport/mcp-webflux-sse-transport[WebFlux SSE Transport] - Reactive HTTP streaming with Spring WebFlux (Client & Server)
** link:https://github.com/spring-projects-experimental/spring-ai-mcp/tree/main/mcp-transport/mcp-webmvc-sse-transport[WebMvc SSE Transport] - Spring MVC based SSE transport (Server only).
** link:https://github.com/modelcontextprotocol/java-sdk/tree/main/mcp-transport/mcp-webflux-sse-transport[WebFlux SSE Transport] - Reactive HTTP streaming with Spring WebFlux (Client & Server)
** link:https://github.com/modelcontextprotocol/java-sdk/tree/main/mcp-transport/mcp-webmvc-sse-transport[WebMvc SSE Transport] - Spring MVC based SSE transport (Server only).
You can use the core `HttpClientSseClientTransport` transport as a SSE client.
=== xref:spring-mcp.adoc[Spring AI MCP]
Spring integration features:
* Spring AI tool/function calling system integration
* Bidirectional conversion between Spring AI function callbacks and MCP tools
* JSON schema generation for tool input validation
* Automatic type conversion and error handling
* Spring-friendly MCP client abstractions
* Auto-configurations (WIP)
== Getting Started
[tabs]
@ -49,27 +39,22 @@ Maven::
----
<!-- Core MCP -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
</dependency>
<!-- Optional: WebFlux SSE transport -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-webflux-sse-transport</artifactId>
</dependency>
<!-- Optional: WebMVC SSE transport -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<groupId>org.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-webmvc-sse-transport</artifactId>
</dependency>
<!-- Optional: Spring AI integration -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-ai-mcp</artifactId>
</dependency>
----
+
Add Spring milestone repository:
@ -93,10 +78,9 @@ Gradle::
[source,groovy]
----
dependencies {
implementation 'org.springframework.experimental:mcp' // Core
implementation 'org.springframework.experimental:mcp-webflux-sse-transport' // Optional
implementation 'org.springframework.experimental:mcp-webmvc-sse-transport' // Optional
implementation 'org.springframework.experimental:spring-ai-mcp' // Optional
implementation 'org.modelcontextprotocol.sdk:mcp' // Core
implementation 'org.modelcontextprotocol.sdk:mcp-webflux-sse-transport' // Optional
implementation 'org.modelcontextprotocol.sdk:mcp-webmvc-sse-transport' // Optional
}
repositories {

View file

@ -1,162 +0,0 @@
= Spring AI MCP Spring
:page-title: Spring AI MCP Spring
:doctype: book
:icons: font
:source-highlighter: highlight.js
:toc: left
Spring Integration module for Model Control Protocol (MCP) that provides Spring-specific functionality for working with MCP clients.
== Overview
The `spring-ai-mcp` module is part of the https://github.com/spring-projects-experimental/spring-ai-mcp[Spring AI MCP] project. It provides Spring Framework integration for the Model Control Protocol (MCP), enabling seamless integration of MCP functionality within Spring applications.
== Features
* Spring integration for MCP clients
* Bidirectional conversion between Spring AI function callbacks and MCP tools
* JSON schema generation for tool input validation
* Automatic type conversion and error handling
* Integration with Spring AI's function calling capabilities
== Main Components
=== McpFunctionCallback
The `McpFunctionCallback` class implements Spring AI's `FunctionCallback` interface and provides integration between Spring AI's function calling system and MCP tools. Key features include:
* Automatic conversion between JSON and Java objects for tool arguments
* Synchronous tool execution support
* Error handling and result formatting
* Integration with Spring AI's function calling system
Example usage:
[source,java]
----
// Create an MCP client
McpSyncClient mcpClient = McpClient.using(transport)
.sync();
// Create a function callback for an MCP tool
Tool calculatorTool = new Tool("calculator", "Basic calculator",
Map.of("operation", "string", "a", "number", "b", "number"));
FunctionCallback callback = new McpFunctionCallback(mcpClient, calculatorTool);
// Use the callback with Spring AI
String result = callback.call("{\"operation\": \"add\", \"a\": 2, \"b\": 3}");
----
=== ToolHelper
The `ToolHelper` utility class facilitates the integration between Spring AI's function callbacks and MCP's tool system. It provides methods for:
* Converting Spring AI's `FunctionCallback` instances to MCP tool registrations
* Generating JSON schemas for tool input validation
* Handling error cases and result formatting
Example usage:
[source,java]
----
// Convert Spring AI function callbacks to MCP tool registrations
List<FunctionCallback> callbacks = List.of(
new CalculatorFunction(),
new WeatherFunction()
);
List<ToolRegistration> tools = ToolHelper.toToolRegistration(callbacks);
// Generate JSON schema for tool inputs
Map<String, Class<?>> inputTypes = Map.of(
"calculator", CalculatorInput.class,
"weather", WeatherInput.class
);
String schema = ToolHelper.generateJsonSchema(inputTypes);
----
==== Converting Function Callbacks to Tools
The `ToolHelper` provides several methods to convert Spring AI function callbacks to MCP tools:
[source,java]
----
// Convert a single function callback
ToolRegistration tool = ToolHelper.toToolRegistration(myCallback);
// Convert multiple callbacks
List<ToolRegistration> tools = ToolHelper.toToolRegistration(callback1, callback2);
// Convert a list of callbacks
List<ToolRegistration> tools = ToolHelper.toToolRegistration(callbackList);
----
==== JSON Schema Generation
The `ToolHelper` can generate JSON schemas for tool input validation:
[source,java]
----
// Using default ObjectMapper
String schema = ToolHelper.generateJsonSchema(inputTypes);
// Using custom ObjectMapper
ObjectMapper mapper = new ObjectMapper();
String schema = ToolHelper.generateJsonSchema(inputTypes, mapper);
----
The generated schema follows the JSON Schema Draft 2020-12 specification and:
* Validates the structure of tool inputs
* Excludes ToolContext class from schema generation
* Uses Jackson's JsonSchemaGenerator for accurate type representation
== Usage
To use this module, add the following dependency to your Maven project:
[source,xml]
----
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-ai-mcp</artifactId>
</dependency>
----
Reffer to the xref:dependency-management.adoc[Dependency Management] page for more information.
=== Example: Creating an MCP Tool Server with Spring AI Functions
[source,java]
----
@Configuration
class McpConfig {
@Bean
McpServer mcpServer(List<FunctionCallback> callbacks) {
// Convert Spring AI callbacks to MCP tools
List<ToolRegistration> tools = ToolHelper.toToolRegistration(callbacks);
return McpServer.using(transport)
.info("spring-ai-server", "1.0.0")
.tools(tools)
.sync();
}
@Bean
FunctionCallback calculatorFunction() {
return FunctionCallback.builder()
.name("calculator")
.description("Basic calculator")
.function(input -> {
// Function implementation
return result;
})
.build();
}
}
----
This configuration:
1. Creates Spring AI function callbacks
2. Converts them to MCP tools using ToolHelper
3. Registers the tools with an MCP server
4. Makes the tools available for discovery and execution by MCP clients