diff --git a/mcp/README.md b/mcp/README.md
new file mode 100644
index 0000000..2e5669f
--- /dev/null
+++ b/mcp/README.md
@@ -0,0 +1,154 @@
+# Model Context Protocol (MCP) Java SDK
+
+A Java implementation of the [Model Context Protocol](https://modelcontextprotocol.io/docs/concepts/architecture) specification, providing both synchronous and asynchronous clients for MCP server interactions.
+
+## Overview
+
+This SDK implements the Model Context Protocol, enabling seamless integration with AI models and tools through a standardized interface. It supports both synchronous and asynchronous communication patterns, making it suitable for various use cases and integration scenarios.
+
+## Features
+
+- Synchronous and Asynchronous client implementations
+- Standard MCP operations support:
+ - Tool discovery and execution
+ - Resource management
+ - Message creation
+ - Server initialization
+- Stdio-based server transport
+- Reactive programming support using Project Reactor
+
+## Installation
+
+Add the following dependency to your Maven project:
+
+```xml
+
+ spring.ai.experimental
+ mcp
+ 1.0.0
+
+```
+
+## Usage
+
+### Async Client Example
+
+```java
+// Create server parameters
+ServerParameters params = ServerParameters.builder("npx")
+ .args("-y", "@modelcontextprotocol/server-everything", "dir")
+ .build();
+
+// Initialize the async client
+Duration timeout = Duration.ofSeconds(10);
+McpAsyncClient client = McpClient.async(
+ new StdioServerTransport(params),
+ timeout,
+ new ObjectMapper()
+);
+
+// Initialize the connection
+client.initialize();
+
+// List available tools
+client.listTools(null).subscribe(result -> {
+ List tools = result.tools();
+ // Process tools...
+});
+
+// Call a tool
+CallToolRequest request = new CallToolRequest(
+ "echo",
+ Map.of("message", "Hello MCP!")
+);
+client.callTool(request).subscribe(result -> {
+ // Handle tool execution result...
+});
+
+// Cleanup
+client.close();
+```
+
+### Sync Client Example
+
+```java
+// Create and initialize sync client
+McpClient syncClient = McpClient.sync(
+ new StdioServerTransport(params),
+ timeout,
+ new ObjectMapper()
+);
+
+// Initialize connection
+syncClient.initialize();
+
+// List tools synchronously
+ListToolsResult tools = syncClient.listTools(null);
+
+// Call tool synchronously
+CallToolResult result = syncClient.callTool("echo", Map.of("message", "Hello!"));
+
+// Cleanup
+syncClient.close();
+```
+
+## Architecture
+
+The SDK follows a layered architecture:
+
+### Core Components
+
+- **McpClient**: Main interface defining the synchronous operations
+- **McpAsyncClient**: Async implementation using Project Reactor
+- **McpSyncClient**: Synchronous wrapper around the async client
+- **McpAsyncTransport**: Transport layer interface
+- **DefaultMcpTransport**: Base transport implementation
+- **StdioServerTransport**: Stdio-based server communication
+
+### Key Interactions
+
+1. Client initialization
+ - Transport setup
+ - Server connection establishment
+ - Protocol handshake
+
+2. Message Flow
+ - Request creation
+ - Transport layer handling
+ - Response processing
+
+3. Tool Execution
+ - Tool discovery
+ - Parameter validation
+ - Execution handling
+ - Result processing
+
+## Error Handling
+
+The SDK provides comprehensive error handling:
+
+- Transport-level errors
+- Protocol violations
+- Tool execution failures
+- Timeout handling
+- Resource management errors
+
+## Contributing
+
+Contributions are welcome! Please feel free to submit a Pull Request.
+
+## License
+
+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.
diff --git a/spring/src/main/java/spring/ai/mcp/McpApplication.java b/spring/src/main/java/spring/ai/mcp/McpApplication.java
index 6d96f76..2b40f13 100644
--- a/spring/src/main/java/spring/ai/mcp/McpApplication.java
+++ b/spring/src/main/java/spring/ai/mcp/McpApplication.java
@@ -28,7 +28,7 @@ public class McpApplication {
return args -> {
var chatClient = chatClientBuilder.defaultFunctions(functionCallbacks.toArray(new McpFunctionCallback[0]))
- .build();
+ .build();
var response = chatClient.prompt("What is the content of the test.txt file?").call().content();
@@ -36,8 +36,8 @@ public class McpApplication {
response = chatClient.prompt(
"Please summarize the content of the test.txt file, covert the result in markdown format and store it into test.md")
- .call()
- .content();
+ .call()
+ .content();
System.out.println("Summary:" + response);
};
}
@@ -46,22 +46,22 @@ public class McpApplication {
public List functionCallbacks(McpSyncClient mcpClient) {
return mcpClient.listTools(null)
- .tools()
- .stream()
- .map(tool -> new McpFunctionCallback(mcpClient, tool))
- .toList();
+ .tools()
+ .stream()
+ .map(tool -> new McpFunctionCallback(mcpClient, tool))
+ .toList();
}
@Bean(destroyMethod = "close")
public McpSyncClient clientSession() {
var stdioParams = ServerParameters.builder("npx")
- .args("-y", "@modelcontextprotocol/server-filesystem",
- "/Users/christiantzolov/Dev/projects/demo/mcp-server/dir")
- .build();
+ .args("-y", "@modelcontextprotocol/server-filesystem",
+ "/Users/christiantzolov/Dev/projects/demo/mcp-server/dir")
+ .build();
McpSyncClient mcpClient = null;
- try {
+ try {
mcpClient = McpClient.sync(new StdioServerTransport(stdioParams),
Duration.ofSeconds(10), new ObjectMapper());
@@ -70,8 +70,7 @@ public class McpApplication {
System.out.println("MCP Initialized: " + init);
return mcpClient;
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new RuntimeException(e);
}
}