- 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 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 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>
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 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>
- 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>
- 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>
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>
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>
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:
c87a0da6d8/schema/2025-03-26/schema.json (L1970-L1973)
- 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>
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>
- Add TestUtil class with findAvailablePort() method to the mcp-test module
- Add findAvailablePort() method to TomcatTestUtil classes
- Replace hardcoded port numbers with dynamic port allocation
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Refactors the MCP logging system to use the exchange mechanism for sending
logging notifications only to specific client sessions rather than broadcasting to all clients.
- Move logging notification delivery from server-wide broadcast to per-session exchange
- Implement per-session minimum logging level tracking and filtering
- Add proper logging level filtering at the exchange level
- Change setLoggingLevel from notification to request/response pattern (breaking change)
- Deprecate global server.loggingNotification in favor of exchange.loggingNotification
- Add SetLevelRequest record to McpSchema
- Add integration test demonstrating filtered logging notifications
Resolves#131
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Adds the ability to specify a base URL for message endpoints in WebMvcSseServerTransportProvider,
enabling proper handling of custom servlet context paths in Spring WebMVC applications.
This ensures that clients receive the correct full endpoint URL when connecting through SSE.
- Add messageBaseUrl field to WebMvcSseServerTransportProvider
- Create new constructor that accepts messageBaseUrl parameter
- Update endpoint event to include base URL in the message endpoint
- Add TomcatTestUtil class to simplify test server creation
- Add WebMvcSseCustomContextPathTests to verify custom context path functionality
- Refactor WebMvcSseIntegrationTests to use the new TomcatTestUtil
Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
These changes are part of the planned deprecation cycle announced in 0.8.0,
with the deprecated classes scheduled for removal in 0.9.0
- Delete WebFluxSseServerTransport, WebMvcSseServerTransport, StdioServerTransport, and HttpServletSseServerTransport
- Remove deprecated interfaces: ServerMcpTransport, ClientMcpTransport
- Delete DefaultMcpSession implementation
- Remove all deprecated test classes for the removed implementations
- Update references to use McpServerTransport and McpClientTransport interfaces
- Split MockMcpTransport into client and server implementations
* Rename MockMcpTransport to MockMcpClientTransport in mcp/src/test
* Create new MockMcpServerTransport implementation
* Add MockMcpServerTransportProvider for server tests
* Mark MockMcpTransport in mcp-test module as deprecated
* Update all test classes to use the new implementations
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit introduces a major refactoring of the MCP Java SDK to implement a session-based architecture
for server-side implementations. The changes improve the SDK's ability to handle multiple concurrent
client connections and provide an API better aligned with the MCP specification.
Key changes:
- Introduce McpServerTransportProvider interface to manage client connections
- Rename ClientMcpTransport to McpClientTransport and ServerMcpTransport to McpServerTransport
- Add exchange objects (McpAsyncServerExchange, McpSyncServerExchange) for client interaction
- Update handler signatures to include exchange parameter: (args) -> result to (exchange, args) -> result
- Rename Registration classes to Specification classes
- Update method names (e.g., rootsChangeConsumers to rootsChangeHandlers)
- Deprecate old interfaces and classes for removal in 0.9.0
- Add migration guide (migration-0.8.0.md)
Resolves#9, #15
Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This change uses VirtualTimeScheduler and pretends enough time has
passed to trigger a timeout on the initialization.
Another problem with reliability of the tests was that the used
testcontainer for the SSE server does not support multiple clients and
the existence of both the global client for the entire suite and some
customized local clients in some tests caused responses to be delivered
to the other client at some racing situations. Now each test creates a
dedicated client and performs cleanup locally.
While these tests were improved, two other issues were found and fixed.
The first one is that the closeGracefully of DefaultMcpSession was not
lazy and would trigger connection disposal before the returned Mono was
subscribed. The second one was dealing with closing the StdIo client
before the process was started. In such a case there should not be an
error but rather a warning and successful completion.
- Add configurable initialization timeout separate from request timeout
- Rename ServletSse* test classes to HttpSse* for better naming consistency
- Replace direct .block() calls with StepVerifier for better reactive testing
- Change ping() method to return Mono instead of Mono
- Improve error handling and reactive programming patterns throughout tests
- Chain reactive operations for cleaner test flow
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>