Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
881e095
feat: implement sampling support for Streamable HTTP transport
andig Jul 27, 2025
d239784
feat: implement server-side sampling support for HTTP transport
andig Jul 27, 2025
dd877e0
fix: replace time.Sleep with synchronization primitives in tests
andig Jul 27, 2025
a4ec0b3
fix: improve request detection logic and add nil pointer checks
andig Jul 27, 2025
1cae3a9
fix: correct misleading comment about response delivery
andig Jul 27, 2025
204b273
fix: implement EnableSampling() to properly declare sampling capability
andig Jul 27, 2025
5d4fb64
fix: prevent panic from unsafe type assertion in example server
andig Jul 27, 2025
4e41f25
fix: add missing EnableSampling() call in interface test
andig Jul 27, 2025
178e234
fix: expand error test coverage and avoid t.Fatalf
andig Jul 27, 2025
27322ca
fix: eliminate recursive response handling and improve routing
andig Jul 27, 2025
d025975
fix: improve sampling response delivery robustness
andig Jul 27, 2025
a9b20be
fix: add graceful shutdown handling to sampling client
andig Jul 28, 2025
b7afbb9
fix: improve context handling in streamable HTTP transport
andig Jul 28, 2025
a664289
fix: improve error message for notification channel queue full condition
andig Jul 28, 2025
bac5dad
refactor: rename struct variable for clarity in message parsing
andig Jul 28, 2025
e69716d
test: add concurrent sampling requests test with response association
andig Jul 28, 2025
e28a859
fix: improve context handling in async goroutine
andig Jul 28, 2025
4fa5295
refactor: replace interface{} with any throughout codebase
andig Jul 28, 2025
3852e2d
fix: improve context handling in async goroutine for StreamableHTTP
andig Jul 28, 2025
83883ed
refactor: remove unused samplingResponseChan field from session struct
andig Jul 28, 2025
9ea4a10
feat: add graceful shutdown handling to sampling HTTP client example
andig Jul 28, 2025
11f8d0e
refactor: remove unused mu field from streamableHttpSession
andig Jul 28, 2025
c1f30be
Merge branch 'main' into http-sampling-improvements
andig Aug 6, 2025
1bda735
Add e2e test
andig Aug 6, 2025
490bcbe
wip
andig Aug 6, 2025
e65ac96
wip
andig Aug 6, 2025
3356446
Merge branch 'main' into http-sampling-improvements and resolve confl…
ezynda3 Sep 27, 2025
a7d4463
fixes
ezynda3 Sep 28, 2025
88a4847
Merge branch 'main' of github.com:mark3labs/mcp-go into http-sampling…
ezynda3 Sep 30, 2025
43c8148
fixes
ezynda3 Sep 30, 2025
5c71064
fix race condition
ezynda3 Sep 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,19 @@ func (c *Client) handleSamplingRequestTransport(ctx context.Context, request tra
}
}

// Fix content parsing - HTTP transport unmarshals TextContent as map[string]any
// Use the helper function to properly handle content from different transports
for i := range params.Messages {
if contentMap, ok := params.Messages[i].Content.(map[string]any); ok {
// Parse the content map into a proper Content type
content, err := mcp.ParseContent(contentMap)
if err != nil {
return nil, fmt.Errorf("failed to parse content for message %d: %w", i, err)
}
params.Messages[i].Content = content
}
}

// Create the MCP request
mcpRequest := mcp.CreateMessageRequest{
Request: mcp.Request{
Expand Down
12 changes: 8 additions & 4 deletions client/transport/streamable_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,10 +594,14 @@ func (c *StreamableHTTP) IsOAuthEnabled() bool {
func (c *StreamableHTTP) listenForever(ctx context.Context) {
c.logger.Infof("listening to server forever")
for {
connectCtx, cancel := context.WithCancel(ctx)
err := c.createGETConnectionToServer(connectCtx)
cancel()

// Use the original context for continuous listening - no per-iteration timeout
// The SSE connection itself will detect disconnections via the underlying HTTP transport,
// and the context cancellation will propagate from the parent to stop listening gracefully.
// We don't add an artificial timeout here because:
// 1. Persistent SSE connections are meant to stay open indefinitely
// 2. Network-level timeouts and keep-alives handle connection health
// 3. Context cancellation (user-initiated or system shutdown) provides clean shutdown
err := c.createGETConnectionToServer(ctx)
if errors.Is(err, ErrGetMethodNotAllowed) {
// server does not support listening
c.logger.Errorf("server does not support listening")
Expand Down
Loading