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.
- 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>
- 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>
- 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>
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>
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>
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>