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>
- 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>
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>
- 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>
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>
- 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>
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>
- 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>
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`.
- 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>
- 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>
- 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
- 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>
- 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>
- 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 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>
- 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-considerationsResolves: #414, #158
Replaces #353
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
- Minor improvement: speed up HttpClientSseClientTransportTests by
reusing the MCP Server container across tests.
- Minor improvement: rename "messageSink" to "deliveredSink" in
HttpClientStreamableHttpTransport#sendMessage
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>
- 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>
- 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>
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>
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>
- 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.