feat: Add MCP server with Server stdio/sse transport improve MCP client
- Implement MCP server with async/sync support and builder pattern configuration - Add Server stdio/SSE transport layers with robust error handling - Convert McpClient and McpServer to interfaces for better extensibility - Add sampling capabilities for LLM interactions (text/image) - Implement dynamic root management and runtime tool management - Add comprehensive prompt and resource capabilities - Add support for dynamic root management (add/remove roots at runtime) Architecture Changes - Introduce registration records for tools, resources, and prompts - Improve thread safety with concurrent collections - Enhance resource template handling - Implement builder patterns for Server/Client capabilities - Add support for server capabilities and implementation info Transport Layer: - Implement SseServerTransport with SSE endpoints - Add StdioServerTransport for process-based communication - Reorganize transport packages for better organization - Improve transport error handling and shutdown processes Documentation: - Add detailed MCP reference documentation - Include architecture diagrams and API documentation - Add comprehensive test coverage for all components - Include sample projects demonstrating stdio/SSE transports BREAKING CHANGES: Transport Package Reorganization - Move StdioClientTransport to o.s.ai.mcp.client.transport - Move SseClientTransport to o.s.ai.mcp.client.transport - Move ServerParameters to o.s.ai.mcp.client.transport - StdioClientTransport.errorHandler changed to private with setter method Migration: Use setErrorHandler() method instead of direct field access API Changes - Replace static factory methods with builder pattern - Update ServerCapabilities to use builder pattern - Make StdioClientTransport.errorHandler private with setter - Replace rootsListProvider with direct root management - Remove deprecated static factory methods Resolves #27,#25,#24,#11 Related to #12
This commit is contained in:
parent
c83a45f880
commit
abd0facf4e
1 changed files with 5727 additions and 471 deletions
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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.server;
|
||||
|
||||
import org.springframework.ai.mcp.server.McpServer.PromptRegistration;
|
||||
import org.springframework.ai.mcp.server.McpServer.ResourceRegistration;
|
||||
import org.springframework.ai.mcp.server.McpServer.ToolRegistration;
|
||||
import org.springframework.ai.mcp.util.Assert;
|
||||
|
||||
/**
|
||||
* Synchronous wrapper around {@link McpAsyncServer} that provides blocking operations.
|
||||
* This class delegates all operations to an underlying async server instance while
|
||||
* providing a synchronous API.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class McpSyncServer {
|
||||
|
||||
/**
|
||||
* The async server to wrap.
|
||||
*/
|
||||
private final McpAsyncServer asyncServer;
|
||||
|
||||
/**
|
||||
* Creates a new synchronous server that wraps the provided async server.
|
||||
* @param asyncServer The async server to wrap
|
||||
*/
|
||||
public McpSyncServer(McpAsyncServer asyncServer) {
|
||||
Assert.notNull(asyncServer, "Async server must not be null");
|
||||
this.asyncServer = asyncServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new tool handler.
|
||||
* @param toolHandler The tool handler to add
|
||||
*/
|
||||
public void addTool(ToolRegistration toolHandler) {
|
||||
this.asyncServer.addTool(toolHandler).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a tool handler.
|
||||
* @param toolName The name of the tool handler to remove
|
||||
*/
|
||||
public void removeTool(String toolName) {
|
||||
this.asyncServer.removeTool(toolName).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available tools has changed.
|
||||
*/
|
||||
public void notifyToolsListChanged() {
|
||||
this.asyncServer.notifyToolsListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available resources has changed.
|
||||
*/
|
||||
public void notifyResourcesListChanged() {
|
||||
this.asyncServer.notifyResourcesListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available prompts has changed.
|
||||
*/
|
||||
public void notifyPromptsListChanged() {
|
||||
this.asyncServer.notifyPromptsListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new resource handler.
|
||||
* @param resourceHandler The resource handler to add
|
||||
*/
|
||||
public void addResource(ResourceRegistration resourceHandler) {
|
||||
this.asyncServer.addResource(resourceHandler).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a resource handler.
|
||||
* @param resourceUri The URI of the resource handler to remove
|
||||
*/
|
||||
public void removeResource(String resourceUri) {
|
||||
this.asyncServer.removeResource(resourceUri).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new prompt handler.
|
||||
* @param promptRegistration The prompt registration to add
|
||||
*/
|
||||
public void addPrompt(PromptRegistration promptRegistration) {
|
||||
this.asyncServer.addPrompt(promptRegistration).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a prompt handler.
|
||||
* @param promptName The name of the prompt handler to remove
|
||||
*/
|
||||
public void removePrompt(String promptName) {
|
||||
this.asyncServer.removePrompt(promptName).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the server gracefully.
|
||||
*/
|
||||
public void closeGracefully() {
|
||||
this.asyncServer.closeGracefully().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the server immediately.
|
||||
*/
|
||||
public void close() {
|
||||
this.asyncServer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying async server instance.
|
||||
* @return The wrapped async server
|
||||
*/
|
||||
public McpAsyncServer getAsyncServer() {
|
||||
return this.asyncServer;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue