Skip to content

feat: Add Spring WebMVC streamable server transport provider #425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jul 30, 2025

Conversation

tzolov
Copy link
Contributor

@tzolov tzolov commented Jul 26, 2025

  • Add WebMvcStreamableServerTransportProvider for non-reactive MCP server support
  • Implement HTTP/SSE transport with session management and graceful shutdown
  • Support GET, POST, DELETE endpoints for MCP protocol operations
  • Add test suite including integration tests with Tomcat
  • Refactor AbstractMcpAsyncServerTests to support multiple transport implementations
  • Provide WebMVC alternative to existing WebFlux streamable transport

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:

  • Unit tests: WebMcpStreamableMcpAsyncServerTests extending the abstract test suite
  • Integration tests: WebMvcStreamableIntegrationTests with comprehensive scenarios including:

Breaking Changes

No breaking changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Implementation Details:

  • WebMvcStreamableServerTransportProvider implements McpStreamableServerTransportProvider
  • Uses Spring WebMVC's RouterFunction for endpoint handling (GET, POST, DELETE)
  • Leverages Server-Sent Events (SSE) via ServerResponse.sse() for streaming responses
  • Maintains session state using ConcurrentHashMap for thread safety
  • Supports message replay functionality for connection recovery
  • Includes builder pattern for easy configuration

Key Features:

  • Session management with unique session IDs
  • Graceful shutdown with proper resource cleanup
  • Message replay support for connection resilience
  • Configurable endpoint paths and DELETE request handling
  • Full compatibility with existing MCP protocol features (tools, resources, prompts, sampling, elicitation)

Testing Strategy:

  • Refactored AbstractMcpAsyncServerTests to use prepareAsyncServerBuilder() pattern
  • This allows the same test suite to validate both WebFlux and WebMVC implementations
  • Added transport-specific integration tests for WebMVC-specific functionality
  • Comprehensive error handling and edge case coverage

chemicL added 9 commits July 18, 2025 12:01
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
…sync server tests

Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
return ServerResponse.status(HttpStatus.SERVICE_UNAVAILABLE).body("Server is shutting down");
}

McpTransportContext transportContext = this.contextExtractor.apply(request);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to make use of this?

return ServerResponse.notFound().build();
}

return session.delete().then(ServerResponse.ok().build());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we need to remove the session from the sessions maps as well?
e.g. this.sessions.remove(sessionId);

@tzolov tzolov force-pushed the streamable-server-webmvc branch from 5c1d0d5 to 5290f39 Compare July 28, 2025 14:54
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
@tzolov tzolov force-pushed the streamable-server-webmvc branch 2 times, most recently from 6e7c16c to fd8d7bb Compare July 29, 2025 16:41
chemicL and others added 5 commits July 30, 2025 11:03
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
…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 <[email protected]>
tzolov added 2 commits July 30, 2025 13:49
- 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 <[email protected]>
@tzolov tzolov force-pushed the streamable-server-webmvc branch from fd8d7bb to 8a2e978 Compare July 30, 2025 12:34
@tzolov tzolov changed the title [WIP] feat: Add Spring WebMVC streamable server transport provider feat: Add Spring WebMVC streamable server transport provider Jul 30, 2025
@tzolov tzolov marked this pull request as ready for review July 30, 2025 12:34
@tzolov tzolov merged commit 7351534 into modelcontextprotocol:main Jul 30, 2025
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants