-
Notifications
You must be signed in to change notification settings - Fork 746
HTTP Sampling Improvements #601
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
Conversation
Implements sampling capability for HTTP transport, resolving issue #419. Enables servers to send sampling requests to HTTP clients via SSE and receive LLM-generated responses. ## Key Changes ### Core Implementation - Add `BidirectionalInterface` support to `StreamableHTTP` - Implement `SetRequestHandler` for server-to-client requests - Enhance SSE parsing to handle requests alongside responses/notifications - Add `handleIncomingRequest` and `sendResponseToServer` methods ### HTTP-Specific Features - Leverage existing MCP headers (`Mcp-Session-Id`, `Mcp-Protocol-Version`) - Bidirectional communication via HTTP POST for responses - Proper JSON-RPC request/response handling over HTTP ### Error Handling - Add specific JSON-RPC error codes for different failure scenarios: - `-32601` (Method not found) when no handler configured - `-32603` (Internal error) for sampling failures - `-32800` (Request cancelled/timeout) for context errors - Enhanced error messages with sampling-specific context ### Testing & Examples - Comprehensive test suite in `streamable_http_sampling_test.go` - Complete working example in `examples/sampling_http_client/` - Tests cover success flows, error scenarios, and interface compliance ## Technical Details The implementation maintains full backward compatibility while adding bidirectional communication support. Server requests are processed asynchronously to avoid blocking the SSE stream reader. HTTP transport now supports the complete sampling flow that was previously only available in stdio and inprocess transports. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This completes the server-side implementation of sampling support for HTTP transport, addressing the remaining requirements from issue #419. Changes: - Enhanced streamableHttpSession to implement SessionWithSampling interface - Added bidirectional SSE communication for server-to-client requests - Implemented session registry for proper response correlation - Added comprehensive error handling with JSON-RPC error codes - Created extensive test suite covering all scenarios - Added working example server with sampling tools Key Features: - Server can send sampling requests to HTTP clients via SSE - Clients respond via HTTP POST with proper session correlation - Queue overflow protection and timeout handling - Compatible with existing HTTP transport architecture 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace flaky time.Sleep calls with proper synchronization using channels and sync.WaitGroup to make tests deterministic and avoid race conditions. Also improves error handling robustness in test servers with proper JSON decoding error checks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Make request vs response detection more robust by checking for presence of "method" field instead of relying on nil Result/Error fields - Add nil pointer check in sendResponseToServer function to prevent panics These changes improve reliability against malformed messages and edge cases. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The comment incorrectly stated that responses are broadcast to all sessions, but the implementation actually delivers responses to the specific session identified by sessionID using the activeSessions registry. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Previously, EnableSampling() was a no-op that didn't actually enable the sampling capability in the server's declared capabilities. Changes: - Add Sampling field to mcp.ServerCapabilities struct - Add sampling field to internal serverCapabilities struct - Update EnableSampling() to set the sampling capability flag - Update handleInitialize() to include sampling in capability response - Add test to verify sampling capability is properly declared Now when EnableSampling() is called, the server will properly declare sampling capability during initialization, allowing clients to know that the server supports sending sampling requests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace unsafe type assertion result.Content.(mcp.TextContent).Text with safe type checking to handle cases where Content might not be a TextContent struct. Now gracefully handles different content types without panicking. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The SamplingInterface test was missing the EnableSampling() call, which is necessary to activate sampling features for proper testing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Replace single error test with comprehensive table-driven tests - Add test cases for invalid request IDs and malformed results - Replace t.Fatalf with t.Errorf to follow project conventions - Use proper session ID format for valid test scenarios 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Remove recursive call in RequestSampling that could cause stack overflow - Remove problematic response re-queuing to global channel - Update deliverSamplingResponse to route responses directly to dedicated request channels via samplingRequests map lookup - This prevents ordering issues and ensures responses reach the correct waiting request 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Modified deliverSamplingResponse to return error instead of just logging - Added proper error handling for disconnected sessions - Improved error messages for debugging - Updated test expectations to match new error behavior 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add signal handling for SIGINT and SIGTERM - Move defer statement after error checking - Improve shutdown error handling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add timeout context for SSE response processing (30s default) - Add timeout for individual connection attempts in listenForever (10s) - Use context-aware sleep in retry logic - Ensure async goroutines properly respect context cancellation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Make error message more descriptive and actionable - Provide clearer debugging information about why the channel is blocked 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Rename 'baseMessage' to 'jsonMessage' for more neutral naming - Improves code readability and follows consistent naming conventions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add test verifying that concurrent sampling requests are handled correctly when the second request completes faster than the first. The test ensures: - Responses are correctly associated with their request IDs - Server processes requests concurrently without blocking - Completion order follows actual processing time, not submission order 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Create new context with 30-second timeout for request handling to prevent long-running handlers from blocking indefinitely. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace all occurrences of interface{} with the modern Go any type alias for improved readability and consistency with current Go best practices. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Create timeout context from parent context instead of context.Background() to ensure request handlers respect parent context cancellation. Addresses review comment about context handling in async goroutine. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The samplingResponseChan field was declared but never used in the streamableHttpSession struct. Remove it and update tests accordingly. Addresses review comment about unused fields in session struct. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add signal handling for SIGINT and SIGTERM to allow graceful shutdown of the sampling HTTP client example. This prevents indefinite blocking and provides better production-ready behavior. Addresses review comment about adding graceful shutdown handling. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Removes unused sync.RWMutex field that was flagged by golangci-lint. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughAdds Content normalization for sampling requests/responses, reworks streamable HTTP listen context and session reuse, implements E2E HTTP sampling tests, introduces mcp.GetTextFromContent, updates an example to use it, and adds/expands sampling documentation. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🧪 Early access (Sonnet 4.5): enabledWe are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience. Note:
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
server/streamable_http.go (1)
639-655
: Populate sampling response payload before deliveryWhen a client POSTs a sampling response, we enqueue a
samplingResponseItem
but never copyresponseMessage.Result
into it. DownstreamRequestSampling
then tries to unmarshal an empty slice, which matches the CI failure (failed to unmarshal sampling response: unexpected end of JSON input
). Please persist the raw payload so the waiting goroutine can decode it.- } else if responseMessage.Result != nil { - // Parse result + } else if responseMessage.Result != nil { + // Preserve the raw result so RequestSampling can decode it later. + response.result = append(json.RawMessage(nil), responseMessage.Result...)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
client/client.go
(1 hunks)client/transport/streamable_http.go
(1 hunks)e2e/sampling_http_test.go
(1 hunks)server/streamable_http.go
(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
client/client.go (1)
mcp/types.go (3)
Content
(952-954)TextContent
(958-965)TextContent
(967-967)
e2e/sampling_http_test.go (8)
mcp/types.go (10)
CreateMessageRequest
(895-898)CreateMessageResult
(915-922)Content
(952-954)SamplingMessage
(925-928)CreateMessageParams
(900-909)InitializeRequest
(433-437)Params
(180-180)InitializeParams
(439-445)Implementation
(521-524)ClientCapabilities
(474-486)mcp/prompts.go (3)
Role
(81-81)RoleAssistant
(85-85)RoleUser
(84-84)mcp/tools.go (6)
Tool
(557-574)Description
(870-874)ToolInputSchema
(627-627)CallToolRequest
(54-58)CallToolResult
(40-51)CallToolParams
(60-64)server/server.go (1)
ServerFromContext
(80-85)server/session.go (1)
ClientSessionFromContext
(82-87)server/streamable_http.go (1)
NewStreamableHTTPServer
(152-167)client/transport/streamable_http.go (2)
NewStreamableHTTP
(131-161)WithContinuousListening
(32-36)client/client.go (2)
NewClient
(70-80)WithSamplingHandler
(41-45)
🪛 ast-grep (0.39.5)
e2e/sampling_http_test.go
[warning] 83-83: "Detected a network listener listening on 0.0.0.0 or an empty string.
This could unexpectedly expose the server publicly as it binds to all
available interfaces. Instead, specify another IP address that is not
0.0.0.0 nor the empty string."
Context: net.Listen("tcp", ":0")
Note: [CWE-200] Exposure of Sensitive Information to an Unauthorized Actor [REFERENCES]
- https://owasp.org/Top10/A01_2021-Broken_Access_Control
(avoid-bind-to-all-interfaces-go)
🪛 GitHub Actions: go
e2e/sampling_http_test.go
[error] 189-189: E2E Test: server sampling request failed due to failed to unmarshal sampling response: unexpected end of JSON input
[error] 306-306: Question tool returned error: failed to unmarshal sampling response: unexpected end of JSON input
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
client/client.go
(1 hunks)client/transport/streamable_http.go
(1 hunks)mcp/utils.go
(1 hunks)server/stdio.go
(1 hunks)server/streamable_http.go
(5 hunks)www/docs/pages/clients/advanced-sampling.mdx
(1 hunks)www/docs/pages/servers/advanced-sampling.mdx
(1 hunks)www/docs/pages/transports/http.mdx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- www/docs/pages/clients/advanced-sampling.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
- client/client.go
🧰 Additional context used
🧬 Code graph analysis (3)
server/stdio.go (2)
mcp/types.go (1)
Content
(952-954)mcp/utils.go (1)
ParseContent
(569-633)
mcp/utils.go (1)
mcp/types.go (2)
TextContent
(958-965)TextContent
(967-967)
server/streamable_http.go (2)
mcp/types.go (1)
Content
(952-954)mcp/utils.go (1)
ParseContent
(569-633)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test
- GitHub Check: coverage
🔇 Additional comments (9)
client/transport/streamable_http.go (1)
597-604
: LGTM! Context handling improved for persistent SSE connections.The change correctly removes per-iteration context timeouts in favor of reusing the parent context for continuous listening. This is the right approach for long-lived SSE connections where:
- Persistent connections should remain open indefinitely
- Network-level timeouts and keep-alives handle connection health
- Parent context cancellation provides clean shutdown
The extensive comments clearly explain the rationale, making the design intent explicit for future maintainers.
www/docs/pages/servers/advanced-sampling.mdx (1)
9-26
: LGTM! Important security guidance for sampling.The addition of the "User Consent Required" section properly emphasizes the MCP spec requirement for human-in-the-loop approval. The documentation:
- Clearly sets expectations about user interaction (review, modification, rejection)
- Provides actionable design recommendations (clear descriptions, graceful error handling, timeouts)
- Aligns with the broader security theme in the HTTP transport documentation
This guidance will help developers implement sampling responsibly.
server/stdio.go (1)
609-620
: LGTM! Content normalization properly implemented.The addition of content parsing for sampling responses correctly handles the case where
Result.Content
arrives asmap[string]any
(from JSON unmarshalling) rather than a properContent
type. The implementation:
- Uses defensive type checking with proper fallback behavior
- Calls
mcp.ParseContent
to convert to the correct Content type (TextContent, ImageContent, etc.)- Handles parse errors gracefully by setting
samplingResp.err
- Preserves existing behavior when content is already properly typed
This aligns with the broader content normalization theme across the PR and ensures sampling responses are properly structured before being passed to handlers.
mcp/utils.go (1)
944-971
: LGTM! Useful utility for text extraction.The new
GetTextFromContent
function provides a convenient way to extract text from various content representations. The implementation:
- Handles multiple content forms (TextContent struct, map[string]any from JSON, plain string)
- Uses clear type switching with appropriate checks (e.g., verifying type="text" in map case)
- Documents the lossy fallback behavior for non-text content
- Appropriately directs users to
ParseContent()
for strict validationThis is a practical helper for scenarios like logging, display, and examples where you need text and can tolerate fallback behavior. The clear documentation about limitations prevents misuse.
www/docs/pages/transports/http.mdx (1)
692-845
: LGTM! Comprehensive sampling documentation.The new "Sampling Support" section provides thorough documentation for StreamableHTTP sampling capabilities. The content:
- Properly emphasizes security requirements with a clear warning about human-in-the-loop approval
- Clearly states technical prerequisites (
WithContinuousListening()
requirement)- Provides practical server-side implementation examples
- Explains the persistent connection architecture clearly
- Honestly documents limitations (need for continuous listening, reconnection concerns)
- Includes a detailed approval flow example showing proper user consent patterns
This gives developers both the security context and practical guidance needed to implement sampling responsibly. The example approval flow is particularly valuable as a reference implementation.
server/streamable_http.go (4)
238-251
: LGTM! Clean session reuse implementation.The function correctly retrieves persistent sessions from
activeSessions
or creates ephemeral ones as needed. The type assertion is properly guarded, and the documentation clearly explains the distinction between persistent and ephemeral sessions.
327-328
: LGTM! Proper integration of session reuse.The change correctly integrates
getOrCreateSession
to reuse persistent sessions for POST requests, enabling bidirectional communication support. The updated comment accurately reflects this behavior.
657-658
: LGTM! Deferred result parsing for proper type handling.Storing the result as
json.RawMessage
is correct here, as it defers unmarshaling until theRequestSampling
method where proper content type conversion occurs.
933-941
: LGTM! Essential content normalization for HTTP transport.The content parsing logic correctly handles the fact that JSON unmarshaling produces
map[string]any
for interface types. Usingmcp.ParseContent
converts this to the proper concreteContent
type (TextContent
,ImageContent
, etc.), which is essential for type safety and proper downstream usage.
Merging this branch changes the coverage (3 decrease, 1 increase)
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
* feat: implement sampling support for Streamable HTTP transport Implements sampling capability for HTTP transport, resolving issue mark3labs#419. Enables servers to send sampling requests to HTTP clients via SSE and receive LLM-generated responses. ## Key Changes ### Core Implementation - Add `BidirectionalInterface` support to `StreamableHTTP` - Implement `SetRequestHandler` for server-to-client requests - Enhance SSE parsing to handle requests alongside responses/notifications - Add `handleIncomingRequest` and `sendResponseToServer` methods ### HTTP-Specific Features - Leverage existing MCP headers (`Mcp-Session-Id`, `Mcp-Protocol-Version`) - Bidirectional communication via HTTP POST for responses - Proper JSON-RPC request/response handling over HTTP ### Error Handling - Add specific JSON-RPC error codes for different failure scenarios: - `-32601` (Method not found) when no handler configured - `-32603` (Internal error) for sampling failures - `-32800` (Request cancelled/timeout) for context errors - Enhanced error messages with sampling-specific context ### Testing & Examples - Comprehensive test suite in `streamable_http_sampling_test.go` - Complete working example in `examples/sampling_http_client/` - Tests cover success flows, error scenarios, and interface compliance ## Technical Details The implementation maintains full backward compatibility while adding bidirectional communication support. Server requests are processed asynchronously to avoid blocking the SSE stream reader. HTTP transport now supports the complete sampling flow that was previously only available in stdio and inprocess transports. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: implement server-side sampling support for HTTP transport This completes the server-side implementation of sampling support for HTTP transport, addressing the remaining requirements from issue mark3labs#419. Changes: - Enhanced streamableHttpSession to implement SessionWithSampling interface - Added bidirectional SSE communication for server-to-client requests - Implemented session registry for proper response correlation - Added comprehensive error handling with JSON-RPC error codes - Created extensive test suite covering all scenarios - Added working example server with sampling tools Key Features: - Server can send sampling requests to HTTP clients via SSE - Clients respond via HTTP POST with proper session correlation - Queue overflow protection and timeout handling - Compatible with existing HTTP transport architecture 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: replace time.Sleep with synchronization primitives in tests Replace flaky time.Sleep calls with proper synchronization using channels and sync.WaitGroup to make tests deterministic and avoid race conditions. Also improves error handling robustness in test servers with proper JSON decoding error checks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: improve request detection logic and add nil pointer checks - Make request vs response detection more robust by checking for presence of "method" field instead of relying on nil Result/Error fields - Add nil pointer check in sendResponseToServer function to prevent panics These changes improve reliability against malformed messages and edge cases. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: correct misleading comment about response delivery The comment incorrectly stated that responses are broadcast to all sessions, but the implementation actually delivers responses to the specific session identified by sessionID using the activeSessions registry. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: implement EnableSampling() to properly declare sampling capability Previously, EnableSampling() was a no-op that didn't actually enable the sampling capability in the server's declared capabilities. Changes: - Add Sampling field to mcp.ServerCapabilities struct - Add sampling field to internal serverCapabilities struct - Update EnableSampling() to set the sampling capability flag - Update handleInitialize() to include sampling in capability response - Add test to verify sampling capability is properly declared Now when EnableSampling() is called, the server will properly declare sampling capability during initialization, allowing clients to know that the server supports sending sampling requests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: prevent panic from unsafe type assertion in example server Replace unsafe type assertion result.Content.(mcp.TextContent).Text with safe type checking to handle cases where Content might not be a TextContent struct. Now gracefully handles different content types without panicking. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: add missing EnableSampling() call in interface test The SamplingInterface test was missing the EnableSampling() call, which is necessary to activate sampling features for proper testing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: expand error test coverage and avoid t.Fatalf - Replace single error test with comprehensive table-driven tests - Add test cases for invalid request IDs and malformed results - Replace t.Fatalf with t.Errorf to follow project conventions - Use proper session ID format for valid test scenarios 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: eliminate recursive response handling and improve routing - Remove recursive call in RequestSampling that could cause stack overflow - Remove problematic response re-queuing to global channel - Update deliverSamplingResponse to route responses directly to dedicated request channels via samplingRequests map lookup - This prevents ordering issues and ensures responses reach the correct waiting request 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: improve sampling response delivery robustness - Modified deliverSamplingResponse to return error instead of just logging - Added proper error handling for disconnected sessions - Improved error messages for debugging - Updated test expectations to match new error behavior 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: add graceful shutdown handling to sampling client - Add signal handling for SIGINT and SIGTERM - Move defer statement after error checking - Improve shutdown error handling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: improve context handling in streamable HTTP transport - Add timeout context for SSE response processing (30s default) - Add timeout for individual connection attempts in listenForever (10s) - Use context-aware sleep in retry logic - Ensure async goroutines properly respect context cancellation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: improve error message for notification channel queue full condition - Make error message more descriptive and actionable - Provide clearer debugging information about why the channel is blocked 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: rename struct variable for clarity in message parsing - Rename 'baseMessage' to 'jsonMessage' for more neutral naming - Improves code readability and follows consistent naming conventions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * test: add concurrent sampling requests test with response association Add test verifying that concurrent sampling requests are handled correctly when the second request completes faster than the first. The test ensures: - Responses are correctly associated with their request IDs - Server processes requests concurrently without blocking - Completion order follows actual processing time, not submission order 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: improve context handling in async goroutine Create new context with 30-second timeout for request handling to prevent long-running handlers from blocking indefinitely. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: replace interface{} with any throughout codebase Replace all occurrences of interface{} with the modern Go any type alias for improved readability and consistency with current Go best practices. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: improve context handling in async goroutine for StreamableHTTP Create timeout context from parent context instead of context.Background() to ensure request handlers respect parent context cancellation. Addresses review comment about context handling in async goroutine. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: remove unused samplingResponseChan field from session struct The samplingResponseChan field was declared but never used in the streamableHttpSession struct. Remove it and update tests accordingly. Addresses review comment about unused fields in session struct. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add graceful shutdown handling to sampling HTTP client example Add signal handling for SIGINT and SIGTERM to allow graceful shutdown of the sampling HTTP client example. This prevents indefinite blocking and provides better production-ready behavior. Addresses review comment about adding graceful shutdown handling. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: remove unused mu field from streamableHttpSession Removes unused sync.RWMutex field that was flagged by golangci-lint. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Add e2e test * wip * wip * fixes * fixes * fix race condition --------- Co-authored-by: andig <cpuidle@gmx.de> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: andig <cpuidle@gmail.com>
Description
Fixes #530
Type of Change
Checklist
MCP Spec Compliance
Additional Information
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation