{{ message }}
feat: Add Spring WebMVC streamable server transport provider#425
Merged
tzolov merged 22 commits intoJul 30, 2025
Conversation
…raction Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
…sync server tests Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
8 tasks
Closed
ba7756f to
9e660d1
Compare
tzolov
commented
Jul 28, 2025
Contributor
Author
There was a problem hiding this comment.
How to make use of this?
tzolov
commented
Jul 28, 2025
Contributor
Author
There was a problem hiding this comment.
I guess we need to remove the session from the sessions maps as well?
e.g. this.sessions.remove(sessionId);
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
5c1d0d5 to
5290f39
Compare
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
6e7c16c to
fd8d7bb
Compare
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
…protocol#425) - Add WebMvcStreamableServerTransportProvider with SSE support for streamable sessions - Support GET, POST, DELETE endpoints for MCP protocol operations - Implement thread-safe SSE operations using ReentrantLock in WebMvcSseServerTransportProvider - Add test infrastructure with AbstractMcpClientServerIntegrationTests - Refactor WebMvcStreamableIntegrationTests to use parameterized tests - Support testing with both HttpClient and WebFlux transports - Add streamable transport tests for both async and sync server modes - Refactor existing WebMVC SSE integration tests to use shared test base - Add error handling improvements in McpStreamableServerSession - Update dependencies: add json-unit-assertj for enhanced JSON testing - Reorganize POM dependencies and add mcp-spring-webflux test dependency This change enables Spring WebMVC applications to use the streamable MCP transport protocol with proper thread safety guarantees and comprehensive test coverage. Related to modelcontextprotocol#72 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
- Wrap consumer, tool, resource, prompt, and completion handler calls with Mono.defer() - Ensures proper lazy evaluation and error handling in reactive streams Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
fd8d7bb to
8a2e978
Compare
This was referenced Oct 14, 2025
rhishirajnema
added a commit
to GreywallSoftware/java-sdk
that referenced
this pull request
Jun 25, 2026
…http + re-apply Veoci customizations (v1.4.0) (#7) * Add missing isInitialized method to McpSyncClient (#181) The isInitialized method is present in McpAsyncClient and needs to be mirrored in McpSyncClient. Signed-off-by: jitokim <pigberger70@gmail.com> * fix: Mockito inline mocking for Java 21+ (#207) Before this fix the execution of the maven surefire plugin with Java 21 logged warnings that mockito should be added as a java agent, because the self-attaching won't be supported in future java releases. In Java 24 the test just broke. This problem is solved by modifying the pom.xml of the parent and doing this changes: * Adding mockito as a java agent. * Removing the surefireArgLine from the properties. This can be added back when it's needed (for example when JaCoCo will be used). Furthermore, the pom.xml in the mcp-spring-* modules now have the byte-buddy dependency included, as the test would otherwise break when trying to mock McpSchema#CreateMessageRequest. Fixes #187 Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Remove temporary delegate impl from McpAsyncServer Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix stdio tests - proper server-everything argument (#237) Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Fix flaky WebFluxSse integration test Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Add Contributing Guidelines and Code of Conduct Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Add note about force pushes Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * feat: Add elicitation support to MCP protocol Implement elicitation capabilities allowing servers to request additional information from users through clients during interactions. This feature provides a standardized way for servers to gather necessary information dynamically while clients maintain control over user interactions and data sharing. - Add ElicitRequest and ElicitResult classes to McpSchema - Implement elicitation handlers in client classes - Add elicitation capabilities to server exchange classes - Add tests for elicitation functionality with various scenarios * feat: WebClient Streamable HTTP support (#292) An implementation of Streamable HTTP Client with WebFlux WebClient. Aside from implementing the specification, several improvements have been incorporated throughout the client-side of the architecture. The changes cover: - resilience tests using toxiproxy in testcontainers - integration tests using updated everything-server with streamableHttp support - improved logging - session invalidation handling (both transport session and JSON-RPC concept of session) - implicit initialization and burst protection (in case of concurrent `Mcp(Sync|Async)Client` use - more logging, e.g. stdio process lifecycle logs Related #72, #273, #253, #107, #105 Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * docs: restructure MCP Java SDK documentation references - Replace single documentation link with organized list of sections - Add direct links to Features, Architecture, Dependencies, Client, and Server docs - Improve navigation and discoverability of specific documentation topics Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix broken link in README Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add AudioContent support to MCP schema (#243) - Add AudioContent record class implementing Annotated and Content interfaces - Update Content sealed interface to permit AudioContent - Add audio type handling in Content.type() method - Include AudioContent in JsonSubTypes annotation for polymorphic deserialization - Add comprehensive tests for AudioContent serialization and deserialization - Update error message test to include audio in known type ids https://github.com/modelcontextprotocol/modelcontextprotocol/blob/c87a0da6d8c2436d56a6398023c80b0562224454/schema/2025-03-26/schema.ts#L987-L1009 * Fix Streamable HTTP WebClient GET SSE handling Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Add sampling functionality tests to MCP client test suites (#255) - Add testSampling() methods to AbstractMcpAsyncClientTests and AbstractMcpSyncClientTests Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: resolve type inference issues in StdioClientTransport - Add explicit Void type parameter to Mono.defer() call - Chain .then() to Mono.delay() to ensure consistent Mono<Void> return type Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: consolidate content annotations into Annotations (#242) Updates all Content types to represent annotations as nested objects instead of directly on the content itself. - Refactor TextContent, ImageContent, and EmbeddedResource to use Annotations object instead of separate audience/priority fields - Add backward-compatible deprecated methods for audience() and priority() accessors - Add parameterized tests for message annotations across different message types (success, error, debug) - Test both text and image content annotations with proper priority and audience validation This brings the implementation in line with the content types as modeled by the specification: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/c87a0da6d8c2436d56a6398023c80b0562224454/schema/2025-03-26/schema.json#L1970-L1973 * Bump the StdioMcpAsyncClientTests initialization timeout to 10s Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * test: enhance resource reading tests (#314) - Implement comprehensive resource content validation for text/plain and application/octet-stream MIME types - Validate resource count expectations (10 resources) - Add elicitation capability testing with ElicitRequest/ElicitResult support - Clean up unused imports (ObjectMapper, ImageFromDockerfile) Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * docs: update loggingNotification javadoc to specify single client * feat: add size field and builder pattern to Resource record (#331) The size field helps hosts display file sizes and estimate context window usage. - Add size parameter to Resource record for tracking raw content size in bytes - Implement Builder pattern for Resource construction with validation - Add deprecated constructor for backwards compatibility - Add tests for builder pattern and field validation Resolves #330 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: support freeform stopReason in sampling (#327) - Add string values and JsonCreator method to StopReason enum - Map unknown stop reason values to UNKNOWN constant for forward compatibility - Add test coverage for unknown stop reason deserialization Spec: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/f5ccad944fdf2b7d9cc70cf817f66ca5a8aa03a4/schema/2024-11-05/schema.ts#L807 Resolves #328 * feat: Improve pagination support on client side (#306) This change enhances the client API by providing both paginated access for fine-grained control and convenience methods for retrieving complete result sets automatically. - Implement "list all" methods that automatically handle pagination using expand/reduce operations - Replace null parameters with McpSchema.FIRST_PAGE constant for better readability - Add tests for both paginated and "list all" functionality - Update method javadocs to clarify pagination behavior - Maintain backward compatibility Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: copy request builder to prevent side effects in HTTP transports (#333) - Add .copy() call before modifying requestBuilder in FlowSseClient - Add .copy() call before modifying requestBuilder in HttpClientSseClientTransport - Prevents unintended mutations of shared builder instances * feat: Added the annotations attribute to McpSchema.Tool (#313) Signed-off-by: Sun Yuhan <sunyuhan1998@users.noreply.github.com> * refactor: consolidate MCP client initialization logic (#334) - Move session setup, completion, and error callbacks into doInitialize method - Rename variables in McpClientSession for better clarity (sink -> pendingResponseSink/deliveredResponseSink) Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: implement resource update notifications (#264) This enables servers to notify clients when specific resources are updated, allowing clients to react to individual resource changes rather than just list changes. - Add ResourcesUpdatedNotification schema with uri field - Add METHOD_NOTIFICATION_RESOURCES_UPDATED constant - Implement notifyResourcesUpdated() methods in McpAsyncServer and McpSyncServer - Add client-side support for resource update consumers and handlers - Client automatically reads updated resource content when notification received - Add tests for both async and sync server implementations Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: Propagate Context to eager connect via McpClientSession (#339) * feat: Propagate Context to eager connect via McpClientSession In order to allow the initial connection to have contextual information in the reactive chain, the McpClientSession should be able to transform the McpClientTransport#connect result, e.g. to attach Context items. This change introduces a new constructor for sessions that makes it possible. Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> --------- Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * typo fix * feat: add pagination support for listRoots operation (#336) - Add nextCursor field to ListRootsResult for cursor-based pagination - Implement automatic pagination in McpAsyncServerExchange.listRoots() - Automatically fetches and combines all pages into single result - Refactor McpAsyncServerExchange.listRoots() to return Collections.unmodifiableList - Update tests to verify pagination functionality - Add test suite for McpAsyncServerExchange covering: - listRoots() pagination scenarios and edge cases - Logging notification with level filtering - Elicitation creation with various capabilities - Message creation with sampling capabilities - Error handling and validation scenarios - Verify sendNotification calls in logging notification tests - Verify sendRequest is never called when capabilities are missing Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: implement ping request handler in MCP async client (#203) - Add ping request handler that responds with empty Map instead of null - Ensure compliance with MCP protocol requirement for ping responses - Add test for ping message request handling Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add ResourceLink content type and ResourceContent interface (#341) - Add ResourceContent interface with common resource metadata methods - Implement ResourceContent in existing Resource class - Add new ResourceLink record class implementing Content and ResourceContent - Update Content interface to support ResourceLink with "resource_link" type (breaking!) - Add tests for ResourceLink serialization/deserialization - Update test expectations to include new resource_link type Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: return immutable lists from list methods (#345) - Wrap the list responses in immutable lists. - Add test to verify the immutable responses. - Better timeout handling Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add ping functionality to MCP server exchanges (#347) - Add ping() method to McpAsyncServerExchange that sends ping requests to clients - Add ping() method to McpSyncServerExchange as synchronous wrapper - Add OBJECT_TYPE_REF constant for ping response type handling - Create McpSyncServerExchangeTests.java with full test coverage - Add ping integration tests across WebFlux, WebMVC, and HttpServlet transports Follow up of #203 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add progress token support and extend Request interface (#352) - Add PaginatedRequest and ReadResourceRequest to Request sealed interface - Add default meta() and progressToken() methods to Request interface - Add _meta parameter support to request classes: - ReadResourceRequest, GetPromptRequest, CallToolRequest - CreateMessageRequest, ElicitRequest, CompleteRequest, PaginatedRequest - Add builder methods for progress token configuration - Add message field to ProgressNotification - Maintain backward compatibility with existing constructors - Add _meta field to the InitialRequest record Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: make McpSyncServerExchange.ping() return response value Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: implement Streamable HTTP HttpClient transport and improve error handling (#337) - Add HttpClientStreamableHttpTransport implementing the 2025-03-26 MCP specification - Add ResponseSubscribers utility for handling different HTTP response body types - Refactor HttpClientSseClientTransport to use reactive streams instead of FlowSseClient - Remove FlowSseClient in favor of reactive stream patterns - Use Disposable-based connection management instead of CountDownLatch - Replace message endpoint discovery with Sinks.One approach - Improve error handling by replacing doOnError/onErrorResume with onErrorComplete - Add test coverage for new Streamable HTTP transport - Add resiliency tests for connection handling and session invalidation BREAKING CHANGE: FlowSseClient has been removed in favor of reactive streams Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Add option for immediate execution in McpSyncServer - The McpSyncServer wraps an async server. By default, reactive operations are scheduled on a bounded-elastic scheduler, to offload blocking work and prevent accidental blocking of non-blocking operations. - With the default behavior, there will be thead ops, even in a blocking context, which means thread-locals from the request thread will be lost. This is inconenvient for frameworks that store state in thread-locals. - This commit adds the ability to avoid offloading, when the user is sure they are executing code in a blocking environment. Work happens in the calling thread, and thread-locals are available throughout the execution. * feat: Add title field support to MCP schema classes (#372) - Add BaseMetadata interface with name() and title() methods for consistent metadata handling - The Prompt, PromptArgument, Resource, ResourceTemplate, ResuorceLink, PromptReference, Tool, and Implementation classes implement the BaseMetadata interface, adding a new, optional title field - Update constructors to support backward compatibility while allowing title specification - Modify ResourceContent interface to extend BaseMetadata - Update all test cases to accommodate new title parameter The title field provides human-readable display names optimized for UI contexts, while name remains for programmatic/logical use. This change maintains backward compatibility. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: extract MCP client initialization logic into LifecycleInitializer (#370) - Create new LifecycleInitializer class to handle protocol initialization phase - Move initialization logic from McpAsyncClient to dedicated initializer - Add javadocs for MCP initialization process - Implement protocol version negotiation and capability exchange - Add exception handling for transport session recovery - Include test suite for LifecyleInitializer - Simplify McpAsyncClient by delegating initialization responsibilities This refactoring improves separation of concerns and makes the initialization process more maintainable and testable. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix non-OK HTTP POST responses handling (#374) Currently, JDK HttpClient SSE implementation incorrectly handles a non-2xx HTTP response code for POST. Instead of immediately failing the caller, it ignores the issue and the user awaits until the timeout kicks in. Set HttpClient to use HTTP/1.1 version explicitly for tests A related problem happened with the WebClient Streamable HTTP implementation, where the error was swallowed for non-400 responses. Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * refactor: deprecate tool spec's arguments-only handler in favor of CallToolRequest (#375) Tool handlers now receive CallToolRequest instead of raw arguments to enable access to additional metadata parameters like progressToken - Deprecate handlers that take only Map<String, Object> arguments - Introduce new handlers that receive the full CallToolRequest object - Maintain backward compatibility with deprecated call handlers - Enhance API to provide access to complete tool request context beyond just arguments - Add builder pattern for AsyncToolSpecification and SyncToolSpecification - Add duplicate tool name validation during server building and runtime registration - Update all test files to use new callTool handlers and builder pattern - Add test coverage for new builder functionality and CallToolRequest handling Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Add legacy constructors for backwards compatibility in McpSchema record types As a followup of #372 introduce new constructors to several record types in McpSchema (Resource, ResourceTemplate, Prompt, PromptArgument, Tool, PromptReference, and ResourceLink) to improve backwards compatibility with previous code versions. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add context support to CompleteRequest for dependent completions - Add CompleteContext record to support contextual completion scenarios - Update CompleteRequest to include context and meta fields with backward-compatible constructors - Modify McpAsyncServer to extract and pass context/meta from request parameters - Add tests for context-aware completions including dependent scenarios - Maintain backward compatibility for existing completion handlers Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: replace string concatenation with {} placeholders in log statements Signed-off-by: Sun Yuhan <sunyuhan1998@users.noreply.github.com> * fix: improve error handling in HttpClientSseClientTransport and add test - Include response body in error messages for better debugging - Change sendHttpPost return type from HttpResponse<Void> to HttpResponse<String> - Use BodyHandlers.ofString() instead of discarding response body - Add testErrorOnBogusMessage test to verify error handling for invalid JSON-RPC messages - Test validates that malformed messages return 400 status with descriptive error message Replace #361 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: jkma <jkma@trip.com> * feat: add structured output support for MCP tools (#357) - Add JsonSchemaValidator interface and DefaultJsonSchemaValidator implementation - put the JsonSchemaValidator classes into a dedicated spec package - add schema caching to DefaultJsonSchemaValidator for better performance - Extend Tool schema to support outputSchema field for defining expected output structure - Add structuredContent field to CallToolResult for validated structured responses - Implement automatic validation of tool outputs against their defined schemas - Add comprehensive test coverage for structured output validation scenarios - Add json-schema-validator and json-unit-assertj dependencies for validation and testing - Update McpServer builders to accept custom JsonSchemaValidator instances - Ensure backward compatibility with existing tools without output schemas This implements the MCP specification requirement that tools with output schemas must provide structured results conforming to those schemas, with automatic validation and error handling for non-conforming outputs. https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * cleanup: Cleaned up some unused imports. (#358) Signed-off-by: Sun Yuhan <sunyuhan1998@users.noreply.github.com> * refactor: reformat McpSchema.java (#392) - Remove unused imports (CallToolResult, TextContent) - Standardize code formatting and indentation throughout - Adjust formatter comments positioning - Improve readability of record definitions and builder classes - Add comprehensive JavaDoc documentation to McpSchema Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: Add _meta support to MCPSchema (#368) - Add _meta field to all MCP schema records for extensible metadata support - Introduce Result and Notification sealed interfaces for better type organization - Update Request interface to include SubscribeRequest and UnsubscribeRequest - Add backwards-compatible constructors for existing record types - Enhance test coverage for metadata field functionality Breaking change: Modifyibng the Request seald inteface is a breaking change. * feat: Add progress notification support for MCP operations (#407) Implement progress tracking for long-running operations with: - New ProgressNotification schema and client/server support - Progress consumer handlers in sync/async client builders - Server exchange methods for sending progress updates - Comprehensive integration tests - Backwards compatibility maintained - Add additional tests Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: Replace Map<String, Object> with CallToolRequest in StructuredOutputCallToolHandler Follow up to #357 to update tool call handler signature from Map<String, Object> to McpSchema.CallToolRequest for consistency with changes in #375. - Change BiFunction parameter from Map<String, Object> to McpSchema.CallToolRequest for better type safety - Update method signature to accept CallToolRequest instead of raw arguments map - Replace toolSpecification.call() with toolSpecification.callHandler() - Migrate to builder pattern for AsyncToolSpecification construction Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: enforce MCP request ID validation requirements Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: improve compatibility with non-compliant MCP servers (#413) Addresses issues with servers like Shopify that violate MCP/HTTP specs: - Prioritize application/json in Accept headers to fix content-type issues - Handle non-compliant notification non-empty responses - Add status code validation and null safety improvements Resolves #406 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: improve SSE event handling to gracefully ignore unrecognized events (#423) - Replace McpError exceptions with debug/warning logs for unrecognized SSE event types - Continue processing instead of failing when encountering unknown SSE events - Update transport implementations: - WebClientStreamableHttpTransport: return empty tuple instead of throwing - WebFluxSseClientTransport: complete stream instead of erroring - HttpClientSseClientTransport: call sink.success() instead of sink.error() - HttpClientStreamableHttpTransport: return empty Flux for unknown events This improves client resilience when servers send non-standard or future SSE event types. Resolves #272 , #223 , #93, #421 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add Streamable HTTP Server abstractions and implement WebFlux transport provider (#420) - Add WebFluxStreamableServerTransportProvider for streamable HTTP sessions - Add WebFluxStatelessServerTransport for stateless HTTP MCP servers - Add McpStatelessServerFeatures, McpStatelessServerHandler, McpStatelessRequestHandler, McpStatelessNotificationHandler - Refactor server architecture to support multiple transport categories: streamable, single-session, stateless - Introduce McpTransportContext for transport-level metadata extraction - Add session management capabilities for streamable HTTP connections - Update MCP protocol version to 2025-03-26 - Add test coverage for new transport implementations - Implement integration tests for both stateless and streamable transports Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: Add Spring WebMVC streamable server transport provider (#425) - Add WebMvcStreamableServerTransportProvider with SSE support for streamable sessions - Support GET, POST, DELETE endpoints for MCP protocol operations - Implement thread-safe SSE operations using ReentrantLock in WebMvcSseServerTransportProvider - Add test infrastructure with AbstractMcpClientServerIntegrationTests - Refactor WebMvcStreamableIntegrationTests to use parameterized tests - Support testing with both HttpClient and WebFlux transports - Add streamable transport tests for both async and sync server modes - Refactor existing WebMVC SSE integration tests to use shared test base - Add error handling improvements in McpStreamableServerSession - Update dependencies: add json-unit-assertj for enhanced JSON testing - Reorganize POM dependencies and add mcp-spring-webflux test dependency - Wrap handler invocations with Mono.defer for lazy evaluation - Wrap consumer, tool, resource, prompt, and completion handler calls with Mono.defer() - Ensures proper lazy evaluation and error handling in reactive streams Related to #72 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * feat: HttpServlet Streamable HTTP server implementation (#290) Implementation of the Streamable HTTP transport provider for the Servlet API. --- Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Zachary German <zdgerman@amazon.com> * Introduce HttpRequest.Builder customizer for HttpClient-based transport - Minor improvement: speed up HttpClientSseClientTransportTests by reusing the MCP Server container across tests. - Minor improvement: rename "messageSink" to "deliveredSink" in HttpClientStreamableHttpTransport#sendMessage * feat: implement MCP-compliant keep-alive functionality for server transports - Add KeepAliveScheduler utility class for configurable periodic session pings - Integrate keep-alive support in WebFlux, WebMVC, and HttpServlet SSE transport providers - Add keepAliveInterval configuration option to all transport provider builders - Deprecate existing constructors in favor of builder pattern with enhanced configuration - Update graceful shutdown to properly clean up keep-alive schedulers - Add unit tests for KeepAliveScheduler functionality Implements MCP specification recommendations for connection health detection: - Configurable ping frequency to suit different network environments - Optional keep-alive (disabled by default) to avoid excessive network overhead - Proper resource cleanup to prevent connection leaks https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/ping#implementation-considerations Resolves: #414, #158 Replaces #353 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Expose the client initialization result - Add getters for both MCP Sync/Async clients Signed-off-by: Ilayaperumal Gopinathan <ilayaperumal.gopinathan@broadcom.com> * feat: implement MCP protocol version per transport support (#404) - Add protocolVersion() method to transport and transport provider interfaces and implementations - Replace hardcoded HTTP header strings with HttpHeaders constants - Update protocol versions to be transport-specific rather than global - Deprecate McpSchema.LATEST_PROTOCOL_VERSION in favor of transport-specific versions - Standardize header names: MCP-Protocol-Version, mcp-session-id, last-event-id - Update clients and servers to use transport.protocolVersion() for initialization - Refactor tests to use transport-specific protocol versions - Include MCP-Protocol-Version header in all GET/POST/DELETE requests - Update WebClientStreamableHttpTransport, WebFluxSseClientTransport, HttpClientSseClientTransport, and HttpClientStreamableHttpTransport Related to #398 , #363 , #250 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add WebMVC and HttpServlet stateless server transports - Add WebMvcStatelessServerTransport for mcp-spring-webmvc module - Add HttpServletStatelessServerTransport for mcp module - Implement builder patterns for AsyncToolSpecification and SyncToolSpecification - Create AbstractStatelessIntegrationTests base class for shared test functionality - Add integration tests for both transport implementations Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Add missing POM descriptions Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Release version 0.11.0 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Release version 0.11.0 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * revert Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Update copyright headers to 2025 and clean up code - Add copyright headers to files missing them - Add blank lines after copyright headers for consistency - Remove unused imports in test files - Remove unnecessary keep-alive warning logs in WebFlux and WebMvc transport providers Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix typo * fix: add backward compatibility for MCP servers returning older protocol versions - Add ProtocolVersions interface with version constants - Change protocolVersion() to protocolVersions() returning List<String> - Streamable HTTP clients now support both 2024-11-05 and 2025-03-26 - Fixes compatibility with MCP servers that return 2024-11-05 instead of 2025-03-26 Resolves #436 Related to #438 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Remove duplicate header MCP_PROTOCOL_VERSION Signed-off-by: Yanming Zhou <zhouyanming@gmail.com> * fix: handle empty JSON responses in ResponseSubscribers - Remove length check in hookOnComplete() to always emit AggregateResponseEvent - Ensures proper completion handling regardless of response content length - Add test for empty application/json responses with 200 OK status * Use `Last-Event-ID` instead of `last-event-id` see https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header Signed-off-by: Yanming Zhou <zhouyanming@gmail.com> * refactor: downgrade unhandled notification logging from error to warn - Change logger.error() to logger.warn() for unhandled notification methods - Log full notification object instead of just method name for better context - Affects McpClientSession, McpServerSession, and McpStreamableServerSession Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix httpRequestCustomizer usage in HttpClientStreamableHttpTransport - Closes #458 Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * feat: handle SSE comment messages - Add support for ignoring SSE comment lines that start with ':' - Add debug logging for comment line processing Resolves #443 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * If a handler throws McpError, use its values for the RPC error Handlers should be able to throw RPC errors and `McpError` is the right exception for that. Improve `DefaultMcpStatelessServerHandler` error handler to check if the exception is `McpError` and, if so, use it to build the RPC error result instead of re-writing as `INTERNAL_ERROR`. * feat: Add builder pattern for McpError and mutate method for capabilities - Add builder pattern to McpError for structured error creation with validation - Deprecate McpError(Object) constructor in favor of builder approach - Add mutate() method to server capabilities for creating modified copies Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: extract common integration test logic into abstract base classes (#473) refactor: extract common integration test logic into abstract base classes - Move duplicated test methods from WebFlux and WebMvc integration test classes to abstract base classes - WebFluxSseIntegrationTests, WebFluxStreamableIntegrationTests now extend AbstractMcpClientServerIntegrationTests - WebFluxStatelessIntegrationTests, WebMvcStatelessIntegrationTests now extend AbstractStatelessIntegrationTests - Each concrete test class now only implements transport-specific setup methods (prepareClients, prepareAsyncServerBuilder, prepareSyncServerBuilder) - Eliminates ~1300+ lines of duplicated test code across multiple files - Improves maintainability by centralizing test logic in reusable base classes - Updates WebMvcSseServerTransportProvider to use builder pattern - Adds new HttpServletSseIntegrationTests extending AbstractMcpClientServerIntegrationTests - Removes HttpServletSseServerTransportProviderIntegrationTests - Standardizes timeout configurations and client setup across all integration tests Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: improve integration tests stability - Replace inline StepVerifier assertions with AtomicReference pattern for better testability - Add assertWith() usage for cleaner assertion blocks in async tests - Simplify reactive chains using doOnNext() and thenReturn() patterns - Remove unnecessary Thread.sleep() from elicitation handler - Improve variable naming (rootsRef → toolsRef) for clarity - Update timeout error message assertions to be more specific - Clean up code formatting and remove redundant comments Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: improve streamable HTTP session reinitialization (#459) Implements the MCP spec guidelines for streamable HTTP (re)initialization: - Server MAY terminate session and MUST respond with HTTP 404 for terminated session IDs - Client MUST start new session when receiving HTTP 404 for requests with session ID Changes: - Replace generic McpError with McpTransportException for transport-layer errors - Only throw McpTransportSessionNotFoundException when session ID is present in request (per spec: 404 with session ID means session terminated, without means general error) - Enhance error messages with more context (status codes, response events) - Use RuntimeException for non-transport specific SSE endpoint failures - Ensure consistent error handling across HTTP client transports - Improve error handling with standard Java exceptions. Replace generic McpError with appropriate standard exceptions: - Use IllegalArgumentException for invalid input parameters - Use IllegalStateException for state-related issues - Use RuntimeException wrapper for initialization failures - Use McpError.builder() with proper error codes for protocol errors Fixes #459 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: ServerCapabilities should not enable logging by default (#463) - Change LoggingCapabilities from default-initialized to nullable in ServerCapabilities - Add check if server logging is enabled in McpAsyncClient before setting logging level - Ensure McpAsyncServer always enables logging capabilities when built - Ensure McpStatelessAsyncServer has disabled logging capability by default - Update tests to verify logging capabilities can be null Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: implement identifier-based equals/hashCode for PromptReference (#514) Ensure PromptReference equality is based solely on identifier and type fields, ignoring other fields like title Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: Fix SseLineSubscriber lacking request. (#507) Signed-off-by: He-Pin <hepin1989@gmail.com> * fix: http streamable client connect timeout (#511) * add http streamable client connect timeout * add http sse client connect timeout Co-authored-by: gongwn1 <gongwn1@lenovo.com> * fix: When call the MCP SSE endpoint, the Content-Type header not passed by default (#489) * feat: implement demand-based request handling in ResponseSubscribers (#516) - Add hasRequestedDemand volatile boolean flag to AggregateSubscriber and BodilessResponseLineSubscriber - Modify hookOnSubscribe to request Long.MAX_VALUE only on first demand request - Guard event emission in hookOnComplete with hasRequestedDemand check - Prevents unnecessary data processing when no downstream demand exists - Improves backpressure handling and resource efficiency Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: disable logging capabilities for stateless servers (#517) Remove LoggingCapabilities from McpStatelessServerFeatures.Async constructor as stateless servers do not support setLogging operations. This aligns the async implementation with the sync implementation which already has logging disabled. Follows up on #463 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: Add transport context extraction support to all MCP servers (#477) - Add McpTransportContextExtractor to WebFlux/WebMVC SSE and Streamable transport providers - Enable extraction of HTTP transport metadata (headers, etc.) for use during request processing - Pass transport context through reactive context chain using McpTransportContext.KEY - Add contextExtractor() builder methods for configuring custom extractors - Update HttpServlet transport providers with same context extraction capability - Modify McpServerSession to properly propagate transport context to handlers - Add test coverage with TEST_CONTEXT_EXTRACTOR in integration tests This allows MCP feature implementations to access HTTP transport level metadata that was present at request time, enabling use cases like authentication, request tracing, and custom header processing. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * refactor: move and rename HTTP request customizers to dedicated package (#453) - Move Mcp(Async)HttpRequestCustomizer from client.transport to client.transport.customizer - Rename (Async)HttpRequestCustomizer to Mcp(Async)HttpRequestCustomizer - Add DelegatingMcpAsyncHttpRequestCustomizer and DelegatingMcpSyncHttpRequestCustomizer for composing multiple customizers - Update all references across transport classes and tests - Improve package organization and naming consistency with MCP prefix * Add McpTransportContext to McpSyncClient (#522) * McpSyncClient: introduce McpTransportContext - McpSyncClient should be considered thread-agnostic, and therefore consumers cannot rely on thread locals to propagate "context", e.g. pass down the Servlet request reference in a server context. - This PR introduces a mechanism for populating an McpTransportContext before executing client operations, and reworks the HTTP request customizers to leverage that McpTransportContext. - Move McpTransportContext from server to common package for shared client/server usage - Make McpTransportContext immutable by removing put() and copy() methods - Add static create() factory method for creating contexts with predefined data - Update McpTransportContextExtractor to return context instead of modifying one - Replace DefaultMcpTransportContext mutable implementation with immutable version - Update all transport implementations to use McpTransportContext.EMPTY as default - Rename *HttpRequestCustomizer -> *HttpClientRequestCustomizer - Add end-to-end McpTransportContextIntegrationTests - This PR introduces a breaking change to the Sync/Async request customizers. Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * Use static container in all client and transport tests (#531) - This allows reusing the containerized MCP server for all tests in a single class, significantly speeding up the tests, roughly 10x. Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * test: Add additional MCP transport context integration tests (#529) - Add integration tests for transport context propagation between MCP clients and servers - Test both sync and async server implementations across all transport types (stateless, streamable, SSE) - Cover Spring WebFlux and WebMVC environments with dedicated test suites - Validate context flow through HTTP headers for authentication, correlation IDs, and metadata - Rename existing McpTransportContextIntegrationTests to SyncServerMcpTransportContextIntegrationTests for clarity - Add proper resource cleanup for async clients in teardown methods Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix flakey test in HttpClientStreamableHttpTransportErrorHandlingTest (#535) * test: upgrade mcp-everything-server to v3 and fix resiliency test race condition (#536) - Upgrade Docker test server image from v2 to v3 across all test files - Updates all test files to use the latest version of the mcp-everything-server Docker image (v3) for integration testing. - Fix race condition in async client tests by not advertising roots capability during initialization - Prevents server from listing roots during init which could cause timing issues when disconnecting immediately after initialization - Applied fix to AbstractMcpAsyncClientResiliencyTests (both mcp and mcp-test modules) and HttpSseMcpAsyncClientLostConnectionTests Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf> * fix: filter template resources from standard resource listing (#528) - Add filter to exclude resources with template parameters ({}) from resources/list - Template resources should only appear in resources/templates/list per MCP spec - Add comprehensive test coverage for resource/template separation - Update mock transport utilities for better test support Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * test: ensure proper resource cleanup in integration tests (#537) - Add try-finally blocks to guarantee server cleanup on test completion - Call closeGracefully().block() to ensure synchronous shutdown - Use try-with-resources for client lifecycle management where applicable - Prevent resource leaks and potential test flakiness Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: Add null check for response ID to prevent memory leaks - Check if response.id() is not null before processing in MCP session classes - Log error when MCP response lacks session ID to warn about potential memory leaks - Improve error handling in McpStreamableServerSession with proper error codes The missing null check could lead to memory leaks as pending requests would never be completed when responses lack session IDs. This fix ensures proper handling of such cases with appropriate error logging. Resolves #506 Signed-off-by: Yanming Zhou <zhouyanming@gmail.com> * fix: Skip structured output validation for error tool results This ensures that when a tool handler returns an error result, the structured output schema validation is skipped, preventing validation failures on error responses that don't conform to the expected output schema. - Add validation bypass when CallToolResult.isError() is true in async/stateless servers - Fix async tool handler chaining to properly use then() instead of block() - Add comprehensive tests for structured output with in-handler errors - Improve error handling to use proper JSON-RPC error codes for unknown tools - Add findRootCause utility method for better error diagnostics - Increase test timeouts for stability in StdioMcp client tests. These tests use npx to download and run the MCP "everything" server locally. The first test execution will download the everything server scripts and cache them locally, which can take more than 15 seconds. Subsequent test runs will use the cached version and execute faster. Resolves #538 Related to #422 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Enhance README with project badges Added badges for license, build status, Maven Central, and Java version to README. * LifecycleInitializer recovers from init failures (#549) Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * fix: Add JsonInclude annotation to notification records for proper serialization (#552) Add @JsonInclude(JsonInclude.Include.NON_ABSENT) to ResourcesUpdatedNotification and to LoggingMessageNotification This ensures that absent (null/Optional.empty()) fields are excluded from JSON serialization, preventing potential serialization issues with these MCP notification types. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: support valid JSON value in tool structured content output (#551) - Change CallToolResult.structuredContent type from Map<String,Object> to Object to support both objects and arrays - Update JsonSchemaValidator to validate any Object type, not just Maps - Add test cases for array-type structured output validation - Fix type casting in existing tests to handle the more generic Object type - Deprecate CallToolResult constructors in favor of builder pattern - Update server implementations to use CallToolResult builder This allows tools to return arrays as structured content, not just objects, which is required by the MCP specification for tools with array-type output schemas. It is realated to MPC spec fix: https://github.com/modelcontextprotocol/modelcontextprotocol/issues/834 Fixes #550 BREAKING CHANGE! Migration Guide: ---------------- 1. If you're accessing CallToolResult.structuredContent(): - Add explicit casting when you know it's a Map: Before: result.structuredContent().get("key") After: ((Map<String,Object>) result.structuredContent()).get("key") - Or check the type first: if (result.structuredContent() instanceof Map) { Map<String,Object> map = (Map<String,Object>) result.structuredContent(); // use map } else if (result.structuredContent() instanceof List) { List<?> list = (List<?>) result.structuredContent(); // use list } 2. If you're creating CallToolResult instances: - Switch to using the builder pattern: Before: new CallToolResult(content, isError, structuredContent) After: CallToolResult.builder() .content(content) .isError(isError) .structuredContent(structuredContent) .build() 3. If you're implementing JsonSchemaValidator: - Update your validate() method signature: Before: validate(Map<String,Object> schema, Map<String,Object> structuredContent) After: validate(Map<String,Object> schema, Object structuredContent) Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: Introduce McpJsonMapper interface to decouple from Jackson (#543) This pull request creates two modules, `mcp-json` and `mcp-json-jackson`. It removes the `com.fasterxml.jackson.core:jackson-databind` and `com.networknt:json-schema-validator` dependencies from the `mcp` module. The `mcp` module now only depends on `com.fasterxml.jackson.core:jackson-annotations`. To use Jackson, you have to add `mcp-jackson` to your dependencies in addition to `mcp`. I added the dependency `mcp-jackson` to both `mcp-spring-mvc` and `mcp-spring-webflux` to avoid a breaking change in those modules. It provides two [SPI](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) `JsonSchemaValidatorSupplier` and `JacksonJsonSchemaValidatorSupplier` to allow easy replacement for consumers who don't want to use Jackson. This pull request also ensures no `McpJsonMapper` is instantiated if one is provided via a builder method. Only if the builders don't receive a `McpJsonMapper` mapper, one is instantiated in the `build` method of the builder. The logic behind this is to allow frameworks to provide a `McpJsonMapper` mapper singleton implementation and feed it to the builders without paying the price of instantiating `McpJsonMappers`, which will not be used. The goal is to be able to use the `ObjectMapper` singleton of an application also for the MCP code. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * extract mcp-core (#557) * extract mcp-core - This change extracts classes previously in `mcp` to `mcp-core`; a new module which does not depend on `mcp-json-jackon2`. - `mcp` module is now an umbrella module that brings `mcp-json-jackon2` and `mcp-core` * add mcp-core to bom BREAKING CHANGE: All source code in the previously `mcp` module is moved to the `mcp-core`. the `mcp` now is just an aggregation for `mcp-core` + `mcp-json-jackson2` for backward compatibility. This change won't affect the end users, but will cause conflicts for the existing PRs. * refactor: standardize test parameterization and fix package naming (#556) - Replace @ValueSource with @MethodSource for parameterized tests - Add clientsForTesting() methods to provide test arguments consistently - Remove hardcoded Spring-related labels from framework-agnostic mcp-test module - Move mcp-test's utility classes from io.modelcontextprotocol.utils to io.modelcontextprotocol.util Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: add MCP protocol version 2025-06-18 support for streamable-http and stateless transports (#558) - Set MCP_2025_06_18 as upper supported protocol version for streamable-http and stateless transport - Update LATEST_PROTOCOL_VERSION constant to reflect new upper bound - Update test expectations for new protocol version usage Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix(mcp): skip source/javadoc generation for aggregator module (#559) The mcp module packages dependencies but has no sources, causing Maven release failures. Skip source and javadoc JAR generation to fix deployment errors. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * simplify the mcp module pom Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: handle resource not found according to spec (#567) see: https://modelcontextprotocol.io/specification/2025-06-18/server/resources#error-handling Resource not found should send a JSON RPC response such as: ```json { "jsonrpc": "2.0", "id": 5, "error": { "code": -32002, "message": "Resource not found", "data": { "uri": "file:///nonexistent.txt" } } } ``` This PR also changes some instances where a `McpError` was thrown instead of being passed in the reactive chain with `Mono.error` functional style * feat: add optional lastModified field to Annotations record with backward compatibility (#568) Resolves #565 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: typo MCP_SESSION_ID, keep consistent style with other identifiers (#564) * refactor: Improve resource template support (#576) - Provide separation of concerns between static resources and parameterized resource templates. - Add AsyncResourceTemplateSpecification and SyncResourceTemplateSpecification for both McpServerFeatures and McpStatelessServerFeatures - Change resource template storage from List to Map to acomodate the resource read handler. - Add runtime management methods: addResourceTemplate(), removeResourceTemplate(), listResourceTemplates() - Improve error handling by using IllegalArgumentException/IllegalStateException instead of McpError - Add new interfaces (Meta, Identifier) and reorganize schema hierarchy - Enhance completion request validation with better error messages - Add ResourceTemplate.Builder for easier template construction - Update all server implementations (Async, Sync, Stateless) consistently - Add type-safe constants for reference types (PromptReference.TYPE, ResourceReference.TYPE) - Add tests for new resource template management functionality - Clean up imports and remove unused dependencies Co-authored-by: Pascal Vantrepote <pascal@confluent.io> Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * refactor: improve MCP server resilience and error handling (#579) - Replace McpError with appropriate standard exceptions (IllegalArgumentException, IllegalStateException) for validation errors - Change tool/prompt registration to replace existing items instead of rejecting duplicates with warningsi - Change addTool behavior to replace existing tools instead of throwing errors - Change addPrompt() to allow replacing existing prompts with warning instead of throwing error - Make removal operations idempotent - log warnings instead of throwing errors for non-existent items - Change removePrompt() to log warning instead of throwing error for non-existent prompts - Change removeTool() to gracefully handle non-existent tools with warnings instead of errors - Add listTools() and listPrompts() methods to all server variants (async, sync, stateless) - Add listTools() method to all server classes for tool enumeration - Add listPrompts() method to all server implementations for retrieving registered prompts - Improve error construction using McpError.builder() pattern for protocol-specific errors - Update error handling in session classes to properly propagate McpError JSON-RPC errors - Use proper error codes (INVALID_PARAMS) for prompt not found scenarios - Update tests to reflect new lenient behavior for duplicate registrations and removals - Add aggregateExceptionMessages() utility method utility to aggregate the exception chains - Update McpServerSession and McpStreamableServerSession to use the aggregated errors in the json-rpc-error data section This change makes the MCP server APIs more resilient and user-friendly by using appropriate exception types, supporting item replacement, and providing listing capabilities while maintaining backward compatibility. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: when using JsonTypeInfo.DEDUCTION don’t add include (#587) From the JSonTypeInfo Javadocs: > If deduction is being used annotation properties visible, property and include are ignored. This is causing issues with serialization downstream. * Client: handle server responses with Content-Length: 0 - When the client sends `notification/initalized`, servers must respond with HTTP 202 and an empty body. We checked for the absence of a Content-Type header to verify whether the body was empty. - However, some servers will send an empty body with a Content-Type header, and that header may have an unsupported, default type such as `text/html` or `text/plain`. - Now we we also use the Content-Length header to check for an empty body. This header is optional in HTTP/2, so we do not make it our primary mechanism for detecting empty bodies. - As part of this PR, we also move hard-coded HTTP header names to the HttpHeaders interface. While they are not defined by the MCP spec, they are used by it and are core to implementing the protocol. Therefore, they have their place in a core interface. - Fixes #582 Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * fix: Handle non-compliant notification responses (#589) Ensure warnings are logged for all non-compliant responses to JSON-RPC notifications, including empty responses. Empty responses now display as "[empty]" in log messages for better clarity. Resolves #586 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat(client): add client tool output schema validation and caching (#302) - Add JSON schema validation for tool call results against output schemas - Implement automatic tool output schema caching during initialization - Add `enableCallToolSchemaCaching` configuration option to enable/disable schema caching - Add `JsonSchemaValidator` integration to McpClient builder APIs - Introduce post-initialization hook mechanism for performing operations after successful client initialization - Cache tool output schemas during `listTools` operations when caching is enabled - Validate tool results against cached schemas in `callTool` operations - Return error CallToolResult when validation fails - Add test coverage - Convert validateToolResult from Mono to synchronous method - Throw IllegalArgumentException on validation errors Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Anurag Pant <pantanurag555@github> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf> Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Add section describing our architectural and design choices (#595) Co-authored-by: Adib Saikali <asaikali@gmail.com> Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> * Update theREADME team section Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * define explicitely that values should always be included in code completions (#601) * define explicitely that values should always be included * spring apply * fix remove name when using deduction (#600) This pull-request removes the name member from the @JsonSubTypes.Type annotations when using JsonTypeInfo.Id.DEDUCTION. With DEDUCTION, Jackson ignores the name entirely because it's inferring the type from the structure. * refactor: change int to Integer for optional numeric fields (#604) Convert primitive int types to Integer wrapper class for: - JSONRPCError.code - CreateMessageRequest.maxTokens (including constructor and builder) This allows these fields to be nullable, properly representing optional parameters in the MCP protocol schema. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: improve URI template matching to properly escape special characters (#599) - Enhanced DefaultMcpUriTemplateManager to use Pattern.quote() for escaping special regex characters like '?' - Replaced simple string replacement regex generation with robust pattern building - Added test case to verify URI matching with query parameters (e.g., "file://name/search?={search}") - Fixed typo: renamed DeafaultMcpUriTemplateManagerFactory to DefaultMcpUriTemplateManagerFactory - Updated all references across server classes and tests Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: allow additional properties by default per JSON Schema spec (#617) - Remove automatic additionalProperties: false injection (JSON Schema spec compliance) - Support String input for structuredContent in validate() method - Move tests to mcp-json-jackson2 module with proper dependencies - Replace wildcard imports with explicit imports Complies with JSON Schema Test Suite: https://github.com/json-schema-org/JSON-Schema-Test-Suite/blob/15e4505/tests/draft2020-12/additionalProperties.json\#L112 Fixes #584 BREAKING CHANGE: Additional properties now allowed by default when not explicitly specified. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Close McpTransportSession on transport close (#632) * Client HTTP transports: use McpTransportSession interface instead of concrete types * Streamable HTTP tranports: .closeGracefully closes the session Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * Fix: McpAsyncClient#listTools prevent infinite recursion (#631) * Fix: prevent infinite recursion in listTools() when nextCursor is empty string Signed-off-by: lance <leehaut@gmail.com> * chore: standardize client/server implementation names and version (#642) Unifies client/server implementation names under "Java SDK" branding and updates all versions to 0.15.0. Resolves: #638 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Update dependencies minor versions to fix build on JDK 25 (#640) * Support o.s.h.HttpHeaders from both 6.x and 7.x branches to enable migration to Spring 7 (#639) * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * feat: enhance error handling with custom error code preservation (#653) - Improve McpClientSession error handling to preserve custom error codes and data from McpError instances. - Add aggregated exception messages to error data field for better debugging. - Include test coverage for various McpClientSession error scenarios. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Bump json-schema-validator from 1.5.7 to 2.0.0 (#660) * fix: JSONRPCResponse JavaDoc (#657) * fix(docs): Remove broken @see link in resourceTemplates Javadoc (#614) * feat(schema): support Object type for progressToken (#663) Change progressToken from String to Object throughout McpSchema to allow both String and Number token types. This makes it compliant with the MCP spec. Resolves: #659 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * Fix experimental client capabilities tests (#670) Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * Fix typo in test name: testPingWithEaxctExceptionType -> testPingWithExactExceptionType * Client transports: make #protocolVersions() configurable (#669) Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * WebClientStreamableHttpTransport: use Spring-5 compatible methods (#649) Signed-off-by: He-Pin <hepin1989@gmail.com> Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * fix the baseUrl is configured with a trailing slash Signed-off-by: lance <leehaut@gmail.com> Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * WebMvcSseServerTransportProvider: do not include session ID in SSE event - This aligns messages with WebFluxSseServerTransportProvider Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * refactor: use builder pattern for CallToolResult and Resource (#652) * use builder pattern for CallToolResult * use builder pattern for Resource * simplify lambda expressions in tests * Basic version negotiation capabilities - We do not support full version negotiation, but this commit allows the client to the send the correct version to match that of the server. - There is one limitation: the GET /mcp request happens too early, before we have deserialized the initialization response, so we do not know the negotiated version yet. This request will have the client latest version as Mcp-Protocol-Version value. Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf> * Revert "WebClientStreamableHttpTransport: use Spring-5 compatible methods (#649)" (#696) This reverts commit 67f8eabb7a0ab70b43b5223768b3aaafd243c843. * Next development version Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> * fix: Fixed html encoding in javadoc (#727) * fix: Enable javadoc generation for modules with OSGi metadata (#705) fix: enable javadoc HTML generation by using legacyMode * fix: Support form and url fields in Elicitation capability per 2025-11-25 spec (#731) Update the ClientCapabilities.Elicitation record to accept optional "form" and "url" fields as defined in the MCP 2025-11-25 specification. Previously, deserializing an InitializeRequest with `{"capabilities":{"elicitation":{"form":{}}}}` would fail with UnrecognizedPropertyException because the Elicitation record was empty. Changes: - Add nested Form and Url marker records to Elicitation - Add no-arg constructor for backward compatibility (serializes to {}) - Add elicitation(boolean form, boolean url) builder method - Add comprehensive tests for deserialization and serialization Fixes #724 * add 2025-11-25 version to ProtocolVersions (#733)…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Related to #72
NOTE: built on top and depending on the #420
This PR adds Spring WebMVC streamable server transport provider support to the MCP Java SDK, providing a non-reactive alternative to the existing WebFlux implementation for HTTP/SSE-based MCP servers.
How Has This Been Tested?
The implementation has been thoroughly tested with:
WebMcpStreamableMcpAsyncServerTestsextending the abstract test suiteWebMvcStreamableIntegrationTestswith comprehensive scenarios including:Breaking Changes
No breaking changes.
Types of changes
Checklist
Additional context
Implementation Details:
WebMvcStreamableServerTransportProviderimplementsMcpStreamableServerTransportProviderRouterFunctionfor endpoint handling (GET, POST, DELETE)ServerResponse.sse()for streaming responsesConcurrentHashMapfor thread safetyKey Features:
Testing Strategy:
AbstractMcpAsyncServerTeststo useprepareAsyncServerBuilder()pattern