Skip to content

feature: Support log/cancelled/progress notification #329

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

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

dugenkui03
Copy link
Collaborator

@dugenkui03 dugenkui03 commented May 24, 2025

Description

Fixes #321.

The SDK currently supports sending any notification anywhere (without even worrying about any restrictions), so this PR is more like a sugar method.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • MCP spec compatibility implementation
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring (no functional changes)
  • Performance improvement
  • Tests only (no functional changes)
  • Other (please describe):

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the documentation accordingly

MCP Spec Compliance

  • This PR implements a feature defined in the MCP specification
  • Link to relevant spec section: Link text
  • Implementation follows the specification exactly

Additional Information

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a session object for handlers, enabling access to session-related capabilities such as sending logging, progress, and cancellation notifications to clients.
    • Added support for structured logging and progress updates from handlers to clients when supported.
    • Extended resource and prompt request parameters to accept additional metadata.
    • Added a generic typed tool handler mechanism with automatic argument binding and validation.
  • Documentation

    • Updated documentation and examples to reflect new handler signatures and demonstrate usage of session-based notifications.
    • Added a new section explaining session-based interactions and notification capabilities.
  • Bug Fixes

    • Improved logging error messages and notification handling in server responses.
  • Tests

    • Updated and expanded tests to cover new session-based notification features and handler signatures.
  • Refactor

    • Unified and streamlined handler function signatures across the codebase to consistently include session context.
    • Improved logging level management and notification method handling for better maintainability.
    • Removed deprecated typed tool handler code and replaced with new generic implementation.

Copy link
Contributor

coderabbitai bot commented May 24, 2025

## Walkthrough

This change introduces a new `RequestSession` parameter to all tool, resource, and prompt handler signatures, enabling handlers to send logging, progress, and cancellation notifications to clients. It adds a `RequestSession` struct and related methods, updates internal server logic, adjusts tests and examples, and updates documentation to reflect the new handler interface and session capabilities.

## Changes

| Files/Paths                                                                 | Change Summary                                                                                  |
|-----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| README.md                                                                   | Updated all handler signatures to include `RequestSession`; added documentation and examples for session-based notifications. |
| mcp/types.go, mcp/prompts.go                                                | Added/updated method constants for notifications, extended request structs for metadata, removed notification structs, added log level filtering. |
| mcp/utils.go                                                                | Removed helper functions and type checks for now-removed notification structs.                  |
| server/request_session.go (new)                                             | Introduced `RequestSession` struct with methods for sending log, progress, and cancellation notifications. |
| server/server.go                                                            | Updated handler function types and invocations to use `RequestSession`; adjusted notification sending and logging level handling. |
| server/typed_tools_handler_func.go (new), mcp/typed_tools.go (removed)      | Moved typed tool handler logic to `server` package, updated to support `RequestSession`.        |
| server/request_handler.go                                                   | Ensured context carries request ID for non-notification messages.                              |
| server/session.go, server/sse.go, server/stdio.go, server/streamable_http.go| Updated session interfaces and structs to support logger name and logging level.                |
| server/session_test.go, server/server_test.go, server/resource_test.go, server/server_race_test.go, server/sse_test.go, server/stdio_test.go, server/streamable_http_test.go | Updated all handler/test function signatures to include `RequestSession`; added session logging methods to test clients. |
| client/inprocess_test.go, client/sse_test.go                                | Updated handler signatures in tests; added/verified notification handling in SSE client tests.  |
| examples/custom_context/main.go, examples/dynamic_path/main.go, examples/everything/main.go, examples/typed_tools/main.go | Updated all handler signatures to include `RequestSession`.                                    |
| server/typed_tools_handler_func_test.go                                     | Updated test package, imports, and handler signatures to use `RequestSession`.                 |
| mcptest/mcptest_test.go                                                     | Updated test handler signature to include `RequestSession`.                                    |

## Assessment against linked issues

| Objective                                                                                                         | Addressed | Explanation                                                                 |
|-------------------------------------------------------------------------------------------------------------------|-----------|-----------------------------------------------------------------------------|
| Pass session/capability object (like `RequestSession`) to all handler types to enable log/progress/cancel notification (#321) ||                                                                             |
| Provide methods on session object for sending log, progress, and cancellation notifications (#321)                ||                                                                             |
| Update documentation and examples to show new handler signatures and notification usage (#321)                    ||                                                                             |

## Assessment against linked issues: Out-of-scope changes

| Code Change                                                                                     | Explanation                                                                                 |
|------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
| Removal of `TypedToolHandlerFunc` and `NewTypedToolHandler` from `mcp/typed_tools.go`           | This refactoring moves typed tool handler logic to the `server` package rather than adding to #321 objectives directly. |
| Addition of `loggerName` fields and `GetLoggerName()` methods in various session structs        | These changes enhance session logging capabilities but are not explicitly required by #321. |
| Changes to `levelToSeverity` map and `LoggingLevel.Allows` method                              | These additions improve log level filtering but are not explicitly mentioned in #321.      |

## Possibly related PRs

- mark3labs/mcp-go#46: The main PR changes handler function signatures to add a `RequestSession` parameter and introduces the `RequestSession` struct with methods for sending notifications, while the retrieved PR focuses on replacing a global notification channel with per-session notification channels and session management interfaces; thus, although both involve session and notification handling, the main PR’s changes to handler signatures and `RequestSession` usage are related to the retrieved PR’s introduction of per-session notification handling and session interfaces.

## Suggested labels

`type: enhancement`, `area: mcp spec`

## Suggested reviewers

- pottekkat
- robert-jackson-glean

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc8c326 and e56dbd1.

📒 Files selected for processing (7)
  • mcp/utils.go (0 hunks)
  • mcptest/mcptest_test.go (1 hunks)
  • server/server.go (15 hunks)
  • server/sse.go (3 hunks)
  • server/stdio.go (2 hunks)
  • server/streamable_http.go (2 hunks)
  • server/streamable_http_test.go (2 hunks)
💤 Files with no reviewable changes (1)
  • mcp/utils.go
✅ Files skipped from review due to trivial changes (1)
  • mcptest/mcptest_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • server/stdio.go
  • server/streamable_http.go
  • server/sse.go
  • server/streamable_http_test.go
  • server/server.go
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dugenkui03 dugenkui03 force-pushed the support-RequestContext-with-logging-progress-cancellation branch from 619d10d to 5697131 Compare May 24, 2025 20:52
@dugenkui03 dugenkui03 marked this pull request as ready for review May 25, 2025 19:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🔭 Outside diff range comments (2)
mcp/types.go (1)

214-244: ⚠️ Potential issue

Critical: Data race detected in NotificationParams.UnmarshalJSON.

The pipeline detected a data race in this method. The issue occurs because:

  1. Maps are initialized without synchronization (lines 223-228)
  2. Multiple goroutines might unmarshal the same NotificationParams instance concurrently
  3. Map writes are not thread-safe

This could cause runtime panics or data corruption in production.

Consider one of these solutions:

Option 1: Make NotificationParams immutable during unmarshaling

 func (p *NotificationParams) UnmarshalJSON(data []byte) error {
 	// Create a map to hold all fields
 	var m map[string]any
 	if err := json.Unmarshal(data, &m); err != nil {
 		return err
 	}
 
-	// Initialize maps if they're nil
-	if p.Meta == nil {
-		p.Meta = make(map[string]any)
-	}
-	if p.AdditionalFields == nil {
-		p.AdditionalFields = make(map[string]any)
-	}
+	// Create new maps to avoid concurrent writes
+	meta := make(map[string]any)
+	additionalFields := make(map[string]any)
 
 	// Process all fields
 	for k, v := range m {
 		if k == "_meta" {
 			// Handle Meta field
 			if meta, ok := v.(map[string]any); ok {
-				p.Meta = meta
+				meta = meta
 			}
 		} else {
 			// Handle additional fields
-			p.AdditionalFields[k] = v
+			additionalFields[k] = v
 		}
 	}
+
+	// Atomic assignment at the end
+	p.Meta = meta
+	p.AdditionalFields = additionalFields
 
 	return nil
 }

Option 2: Document that NotificationParams instances should not be shared between goroutines during unmarshaling

Add a comment above the struct:

// NotificationParams holds notification parameters.
// Note: Instances of this type should not be shared between goroutines
// during JSON unmarshaling as it may cause data races.
type NotificationParams struct {
🧰 Tools
🪛 GitHub Actions: go

[error] 218-239: Data race detected in NotificationParams.UnmarshalJSON method. Concurrent map writes and reads occur during JSON unmarshalling, causing race conditions.

client/sse_test.go (1)

45-108: ⚠️ Potential issue

Address data race conditions in notification testing.

The pipeline failures indicate data race conditions in this test section. The issue likely stems from concurrent access to shared notification collections without proper synchronization.

The test modifies shared variables (notificationNum, messageNotification, progressNotifications) from multiple goroutines without synchronization. Consider using proper synchronization mechanisms:

+import "sync"

+var (
+    mu sync.Mutex
+    notificationNum int
+    messageNotification *mcp.JSONRPCNotification
+    progressNotifications []*mcp.JSONRPCNotification
+)

 client.OnNotification(func(notification mcp.JSONRPCNotification) {
+    mu.Lock()
+    defer mu.Unlock()
     if notification.Method == string(mcp.MethodNotificationMessage) {
         messageNotification = &notification
     } else if notification.Method == string(mcp.MethodNotificationProgress) {
         progressNotifications = append(progressNotifications, &notification)
     }
     notificationNum += 1
 })
🧹 Nitpick comments (4)
server/server.go (1)

335-335: Consistent type conversion for notification methods.

All notification method calls correctly convert MCPMethod to string. While this is functionally correct, consider updating SendNotificationToAllClients to accept MCPMethod directly to avoid these conversions throughout the codebase.

Also applies to: 350-350, 382-382, 409-409, 429-429, 471-471, 498-498

client/sse_test.go (1)

601-601: Remove debug print statements.

The println statements appear to be debug leftovers and should be removed from production test code.

-        println(notification.Method)
-        println(fmt.Sprintf("%v", result))
-        println(notification.Method)

Also applies to: 654-654, 690-690

README.md (1)

95-95: Fix markdown formatting issues.

Static analysis detected formatting inconsistencies that should be addressed for better documentation quality.

-  - [RequestContext](#RequestContext)
+  - [RequestContext](#requestcontext)

Also, ensure consistent use of spaces instead of hard tabs throughout the code examples in the RequestContext section (lines 546-564).

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

95-95: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


95-95: Link fragments should be valid
Expected: #requestcontext; Actual: #RequestContext

(MD051, link-fragments)

examples/everything/main.go (1)

389-432: Consider migrating to new RequestContext notification methods.

The handleLongRunningOperationTool function still uses the older server.SendNotificationToClient approach. Consider updating it to use the new requestContext.SendProgressNotification method for consistency and better encapsulation.

-        server := server.ServerFromContext(ctx)
-        err := server.SendNotificationToClient(
-            ctx,
-            "notifications/progress",
-            map[string]any{
-                "progress":      i,
-                "total":         int(steps),
-                "progressToken": progressToken,
-                "message":       fmt.Sprintf("Server progress %v%%", int(float64(i)*100/steps)),
-            },
-        )
+        message := fmt.Sprintf("Server progress %v%%", int(float64(i)*100/steps))
+        total := float64(steps)
+        err := requestContext.SendProgressNotification(ctx, float64(i), &total, &message)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 243a292 and 5fc3c83.

⛔ Files ignored due to path filters (1)
  • server/internal/gen/request_handler.go.tmpl is excluded by !**/gen/**
📒 Files selected for processing (28)
  • README.md (12 hunks)
  • client/inprocess_test.go (3 hunks)
  • client/sse_test.go (6 hunks)
  • examples/custom_context/main.go (1 hunks)
  • examples/dynamic_path/main.go (1 hunks)
  • examples/everything/main.go (10 hunks)
  • examples/typed_tools/main.go (2 hunks)
  • mcp/prompts.go (1 hunks)
  • mcp/typed_tools.go (0 hunks)
  • mcp/types.go (3 hunks)
  • mcp/utils.go (0 hunks)
  • mcptest/mcptest_test.go (1 hunks)
  • server/request_context.go (1 hunks)
  • server/request_handler.go (1 hunks)
  • server/resource_test.go (5 hunks)
  • server/server.go (15 hunks)
  • server/server_race_test.go (7 hunks)
  • server/server_test.go (17 hunks)
  • server/session.go (1 hunks)
  • server/session_test.go (9 hunks)
  • server/sse.go (2 hunks)
  • server/sse_test.go (3 hunks)
  • server/stdio.go (2 hunks)
  • server/stdio_test.go (1 hunks)
  • server/streamable_http.go (3 hunks)
  • server/streamable_http_test.go (2 hunks)
  • server/typed_tools_handler_func.go (1 hunks)
  • server/typed_tools_handler_func_test.go (14 hunks)
💤 Files with no reviewable changes (2)
  • mcp/utils.go
  • mcp/typed_tools.go
🧰 Additional context used
🧬 Code Graph Analysis (14)
server/request_handler.go (1)
mcp/types.go (1)
  • NewRequestId (259-261)
mcp/prompts.go (1)
mcp/types.go (1)
  • Meta (135-147)
examples/custom_context/main.go (1)
server/request_context.go (1)
  • RequestContext (13-17)
examples/dynamic_path/main.go (2)
mcp/tools.go (3)
  • NewTool (567-589)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
server/request_context.go (1)
  • RequestContext (13-17)
server/server_race_test.go (5)
server/request_context.go (1)
  • RequestContext (13-17)
mcp/prompts.go (3)
  • GetPromptRequest (20-31)
  • GetPromptResult (35-40)
  • Prompt (46-54)
mcp/tools.go (3)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
  • Description (669-673)
server/server.go (1)
  • ToolHandlerFunc (40-40)
mcp/types.go (2)
  • ReadResourceRequest (526-538)
  • ResourceContents (640-642)
mcptest/mcptest_test.go (2)
server/request_context.go (1)
  • RequestContext (13-17)
mcp/tools.go (2)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
server/stdio_test.go (2)
mcp/tools.go (3)
  • NewTool (567-589)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
server/request_context.go (1)
  • RequestContext (13-17)
server/typed_tools_handler_func.go (3)
server/request_context.go (1)
  • RequestContext (13-17)
mcp/tools.go (2)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
mcp/utils.go (1)
  • NewToolResultError (241-251)
server/sse_test.go (2)
mcp/tools.go (3)
  • NewTool (567-589)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
server/request_context.go (1)
  • RequestContext (13-17)
server/streamable_http_test.go (2)
server/request_context.go (1)
  • RequestContext (13-17)
mcp/tools.go (2)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
server/streamable_http.go (1)
mcp/types.go (2)
  • LoggingLevel (685-685)
  • LoggingLevelError (692-692)
server/typed_tools_handler_func_test.go (5)
server/request_context.go (1)
  • RequestContext (13-17)
mcp/tools.go (2)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
mcp/utils.go (2)
  • NewToolResultText (175-184)
  • NewToolResultError (241-251)
server/typed_tools_handler_func.go (1)
  • NewTypedToolHandler (13-21)
mcp/types.go (4)
  • Content (782-784)
  • TextContent (788-793)
  • TextContent (795-795)
  • Params (177-177)
server/session_test.go (3)
mcp/types.go (2)
  • LoggingLevel (685-685)
  • LoggingLevelError (692-692)
server/request_context.go (1)
  • RequestContext (13-17)
mcp/tools.go (3)
  • CallToolRequest (46-53)
  • CallToolResult (36-43)
  • NewTool (567-589)
examples/everything/main.go (1)
server/request_context.go (1)
  • RequestContext (13-17)
🪛 GitHub Actions: go
client/sse_test.go

[error] 457-539: Data race detected during execution of TestSSEMCPClient and its subtests. Multiple concurrent goroutines read and write shared variables without synchronization, causing race conditions. Key locations include lines 457-539 in sse_test.go and related code in client.go and transport/sse.go.


[error] 591-762: Data race detected during execution of TestSSEMCPClient.func14 and func15. Multiple concurrent goroutines read and write shared variables without synchronization, causing race conditions.

mcp/types.go

[error] 218-239: Data race detected in NotificationParams.UnmarshalJSON method. Concurrent map writes and reads occur during JSON unmarshalling, causing race conditions.

🪛 markdownlint-cli2 (0.17.2)
README.md

95-95: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


95-95: Link fragments should be valid
Expected: #requestcontext; Actual: #RequestContext

(MD051, link-fragments)


546-546: Hard tabs
Column: 1

(MD010, no-hard-tabs)


547-547: Hard tabs
Column: 1

(MD010, no-hard-tabs)


548-548: Hard tabs
Column: 1

(MD010, no-hard-tabs)


549-549: Hard tabs
Column: 1

(MD010, no-hard-tabs)


550-550: Hard tabs
Column: 1

(MD010, no-hard-tabs)


552-552: Hard tabs
Column: 1

(MD010, no-hard-tabs)


553-553: Hard tabs
Column: 1

(MD010, no-hard-tabs)


554-554: Hard tabs
Column: 1

(MD010, no-hard-tabs)


555-555: Hard tabs
Column: 1

(MD010, no-hard-tabs)


557-557: Hard tabs
Column: 1

(MD010, no-hard-tabs)


558-558: Hard tabs
Column: 1

(MD010, no-hard-tabs)


559-559: Hard tabs
Column: 1

(MD010, no-hard-tabs)


560-560: Hard tabs
Column: 1

(MD010, no-hard-tabs)


561-561: Hard tabs
Column: 1

(MD010, no-hard-tabs)


562-562: Hard tabs
Column: 1

(MD010, no-hard-tabs)


563-563: Hard tabs
Column: 1

(MD010, no-hard-tabs)


564-564: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (53)
server/request_handler.go (1)

57-59: LGTM: Proper request ID context handling.

The else block correctly adds the request ID to the context for non-notification messages, which supports the RequestContext functionality for progress and logging notifications. The logic properly distinguishes between notifications (ID == nil) and regular requests.

mcp/prompts.go (1)

27-29: LGTM: Well-implemented metadata field for request context.

The addition of the Meta field to GetPromptRequest.Params is correctly implemented with:

  • Appropriate pointer type for optional metadata
  • Proper JSON tag with omitempty
  • Clear documentation explaining its purpose
  • Consistent with the broader RequestContext support for progress and logging notifications
examples/custom_context/main.go (1)

82-82: LGTM: Proper handler signature update.

The addition of the requestContext server.RequestContext parameter correctly updates the tool handler signature to support the new context functionality for logging, progress, and cancellation notifications. The parameter placement between ctx and request follows the established pattern across the codebase.

server/resource_test.go (2)

31-31: LGTM: Test handler signatures updated correctly.

The anonymous resource read handler functions have been properly updated to include the new requestContext RequestContext parameter, maintaining consistency with the updated handler signature requirements throughout the codebase.

Also applies to: 50-50, 111-111, 167-167


87-87: LGTM: Proper string conversion in assertion.

The explicit conversion to string ensures type consistency in the assertion, which is a good practice when comparing constants to string values.

mcptest/mcptest_test.go (1)

53-53: LGTM! Handler signature correctly updated for RequestContext support.

The function signature has been properly updated to include the new RequestContext parameter, aligning with the broader refactoring to support logging, progress, and cancellation notifications. The parameter placement between ctx and request is consistent with the pattern used across the codebase.

server/sse.go (1)

79-82: LGTM! Logger name getter method correctly implemented.

The GetLoggerName() method properly returns the logger name field as expected by the ClientSession interface.

examples/dynamic_path/main.go (1)

22-24: LGTM! Tool handler signature correctly updated.

The tool handler function signature has been properly updated to include the RequestContext parameter, maintaining consistency with the new handler interface pattern. The function logic remains unchanged, which is appropriate for this signature update.

server/session.go (1)

24-26: LGTM! Interface correctly extended with logger name support.

The addition of GetLoggerName() *string to the ClientSession interface properly supports the enhanced logging capabilities introduced in this PR. The method signature is consistent with the implementations in the session types.

server/stdio.go (1)

105-107: LGTM: Method implementation is correct.

The GetLoggerName() method correctly returns the logger name pointer, following the expected interface pattern.

examples/typed_tools/main.go (2)

76-76: LGTM: RequestContext parameter addition is correct.

The function signature correctly includes the new RequestContext parameter, enabling the handler to send logging, progress, and cancellation notifications to clients.


67-67:

✅ Verification successful

Verify the typed tool handler package migration.

The typed tool handler functionality appears to have moved from mcp.NewTypedToolHandler to server.NewTypedToolHandler. This is a breaking change that could affect other code using the old API.

Please verify that all references to mcp.NewTypedToolHandler have been updated across the codebase:


🏁 Script executed:

#!/bin/bash
# Description: Search for any remaining references to the old mcp.NewTypedToolHandler
# Expected: No occurrences should be found if migration is complete

echo "Searching for old mcp.NewTypedToolHandler references..."
rg "mcp\.NewTypedToolHandler" --type go

echo -e "\nSearching for new server.NewTypedToolHandler references..."
rg "server\.NewTypedToolHandler" --type go

Length of output: 436


Package migration verified: all references to mcp.NewTypedToolHandler removed

  • No occurrences of mcp.NewTypedToolHandler remain in the codebase.
  • server.NewTypedToolHandler is used only in examples/typed_tools/main.go as intended.

This breaking change is fully applied and requires no further updates.

server/stdio_test.go (1)

143-143: LGTM: Test handler signature correctly updated.

The anonymous tool handler function signature has been properly updated to include the RequestContext parameter, maintaining consistency with the new handler interface.

server/server_race_test.go (2)

42-42: LGTM: Consistent RequestContext parameter additions.

All handler function signatures have been correctly updated to include the RequestContext parameter, maintaining consistency across the test suite.

Also applies to: 52-52, 63-63, 74-74, 105-105, 124-124, 172-172, 177-177


82-84: Excellent middleware pattern implementation.

The middleware function correctly forwards the RequestContext parameter to the next handler in the chain, demonstrating proper middleware composition with the new signature.

server/streamable_http.go (1)

529-539: LGTM! Thread-safe logging level implementation.

The atomic operations for SetLogLevel and GetLogLevel are correctly implemented for thread safety. The fallback to mcp.LoggingLevelError when no level is set provides a sensible default.

server/sse_test.go (3)

577-577: LGTM! Consistent signature update.

The handler signature is correctly updated to include the RequestContext parameter, aligning with the new API pattern. The handler logic remains unchanged, which is appropriate for this test.


1186-1188: LGTM! Consistent signature update.

The handler signature is correctly updated to include the RequestContext parameter. The implementation remains simple and appropriate for testing purposes.


1338-1338: LGTM! Consistent signature update.

The handler signature is correctly updated to include the RequestContext parameter, maintaining consistency across all test handlers.

server/streamable_http_test.go (2)

42-42: LGTM! Consistent signature update.

The addSSETool handler signature is correctly updated to include the RequestContext parameter, aligning with the new API pattern throughout the codebase.


604-604: LGTM! Consistent signature update.

The test tool handler signature is correctly updated to include the RequestContext parameter, maintaining consistency with the broader refactoring.

server/typed_tools_handler_func.go (2)

9-11: LGTM! Well-designed generic function type.

The TypedToolHandlerFunc[T any] generic type provides excellent type safety for tool handlers while maintaining compatibility with the new RequestContext parameter. The generic constraint [T any] is appropriate for flexible argument binding.


12-21: LGTM! Excellent typed handler wrapper implementation.

The NewTypedToolHandler function provides a clean and type-safe way to handle tool arguments:

  • Proper error handling with descriptive error messages using mcp.NewToolResultError
  • Automatic argument binding via request.BindArguments
  • Consistent signature that integrates well with the RequestContext pattern
  • Clean separation of concerns between argument binding and handler logic

This implementation promotes type safety while maintaining flexibility and good error reporting.

client/inprocess_test.go (3)

30-30: LGTM! Handler signature updated correctly.

The addition of requestContext server.RequestContext parameter to the tool handler follows the correct pattern and aligns with the PR objective to support log/cancelled/progress notifications.


51-51: LGTM! Resource handler signature updated correctly.

The RequestContext parameter addition is consistent with the tool handler change above.


73-73: LGTM! Prompt handler signature updated correctly.

The RequestContext parameter addition maintains consistency across all handler types.

server/server_test.go (4)

163-163: LGTM! Handler signatures updated consistently.

All tool handler function signatures have been correctly updated to include the requestContext RequestContext parameter. The positioning after ctx context.Context is consistent across all handlers.

Also applies to: 168-168, 192-192, 197-197, 233-233, 238-238, 265-265, 271-271


204-204: LGTM! Method constant string conversions are correct.

The explicit conversion of MCP method constants to strings using string() is necessary for proper comparison and follows the updated type system where these constants are now typed.

Also applies to: 246-246, 278-278, 279-279, 303-303, 305-305, 336-336, 846-846, 848-848, 901-901, 903-903, 905-905, 954-954, 956-956


525-533: LGTM! fakeSession interface implementation updated correctly.

The addition of logging-related methods SetLogLevel, GetLogLevel, and GetLoggerName properly implements the updated ClientSession interface with appropriate default values and no-op behavior for testing.


709-709: LGTM! Handler signatures consistently updated.

All prompt, resource template, and tool handler signatures have been correctly updated to include the RequestContext parameter in the proper position.

Also applies to: 1124-1124, 1386-1386, 1473-1473, 1489-1489, 1635-1635, 1806-1806

server/typed_tools_handler_func_test.go (3)

1-1: LGTM! Package restructuring handled correctly.

The change from package mcp to package server and the addition of the mcp package import properly reflect the movement of typed tool handler functionality to the server package.

Also applies to: 7-7


22-22: LGTM! Handler function signatures updated correctly.

All typed handler function signatures have been consistently updated to include the RequestContext parameter in the correct position, maintaining the expected signature pattern.

Also applies to: 88-88, 174-174


23-23: LGTM! Type references properly qualified.

All references to MCP types and utility functions are correctly prefixed with mcp. to reflect the new import structure. The test calls properly pass RequestContext{} as the required parameter.

Also applies to: 30-30, 39-39, 44-44, 54-54, 66-66, 69-69, 73-73, 91-91, 104-104, 108-108, 111-111, 118-118, 127-127, 132-132, 141-141, 145-145, 177-177, 180-180, 214-214, 221-221, 243-243, 248-252, 269-269, 272-276, 298-298, 301-304

server/session_test.go (7)

45-54: LGTM! Test client logging methods properly implemented.

The no-op implementations for SetLogLevel, default error level for GetLogLevel, and nil return for GetLoggerName are appropriate for test clients.


81-90: Consistent logging method implementations.

The logging methods follow the same pattern as other test clients, maintaining consistency across test implementations.


162-171: Consistent test client implementation pattern.


208-210: Completes the SessionWithLogging interface implementation.

Adding GetLoggerName ensures this test client fully implements the updated interface.


224-228: Handler signature correctly updated with RequestContext.

The function signature now includes the RequestContext parameter as per the new API design.


274-274: Correct usage of empty RequestContext in test.

Passing an empty RequestContext{} is appropriate for this test scenario.


393-397: All handler signatures consistently updated.

The tool handler function signatures have been uniformly updated to include the RequestContext parameter.

Also applies to: 598-601, 618-622

mcp/types.go (3)

59-92: Well-structured notification method constants with proper typing.

The explicit MCPMethod typing improves type safety, and the new notification methods for logging, progress, and cancellation align perfectly with the PR objectives. The specification links in comments are helpful.


534-537: Meta field enables progress notifications for resource reads.

Adding the Meta field to ReadResourceRequest parameters allows clients to request progress notifications, which is essential for the new notification features.


698-719: Well-implemented logging level filtering logic.

The Allows method correctly implements severity-based filtering using a clear mapping of levels to numeric severities. The error handling for invalid levels is appropriate.

server/server.go (4)

31-31: Handler function signatures properly updated with RequestContext.

All handler function types now consistently include the RequestContext parameter between context.Context and the request parameter, enabling rich client interaction capabilities.

Also applies to: 34-34, 37-37, 40-40


218-232: Middleware correctly updated to support RequestContext.

The WithRecovery middleware properly forwards the RequestContext parameter while maintaining its panic recovery functionality.


731-732: RequestContext properly created and passed to handlers.

The RequestContext is consistently created with the server instance and request metadata, then passed to all handlers. This enables handlers to send progress, logging, and cancellation notifications.

Also applies to: 738-738, 769-769, 851-852, 1002-1003


610-610: Simplified logging level setting aligns with interface changes.

Directly calling SetLogLevel on clientSession is cleaner than type assertion and aligns with the updated interface design.

server/request_context.go (3)

32-35: Good defensive programming practice.

The method properly checks server capabilities before attempting to send notifications, preventing unnecessary operations when logging is not supported.


94-102: Robust error handling for request ID validation.

The cancellation notification method properly validates the request ID existence and type before proceeding, which prevents runtime panics and provides clear error messages.


25-27:

✅ Verification successful

Potential pointer handling issue in constructor.

The assignment requestContext.progressToken = &requestParamMeta.ProgressToken may be incorrect depending on whether ProgressToken is already a pointer type. If ProgressToken is a pointer, this creates a double pointer which could cause issues when dereferencing in line 76.


🏁 Script executed:

#!/bin/bash
# Description: Check the type definition of ProgressToken in mcp package to verify correct pointer handling

# Search for ProgressToken type definition in mcp package
ast-grep --pattern 'type $_ struct {
  $$$
  ProgressToken $_
  $$$
}'

# Also search for ProgressToken field definitions
rg -A 3 -B 1 "ProgressToken.*string\|ProgressToken.*\*"

Length of output: 866


🏁 Script executed:

#!/bin/bash
# Display the RequestContext struct and progressToken field definitions
rg -n "type RequestContext" -A 5 server/request_context.go
rg -n "progressToken" -A 5 server/request_context.go

Length of output: 972


🏁 Script executed:

#!/bin/bash
# Find the definition of ProgressToken in mcp/types.go
rg -n "type ProgressToken" -A 5 mcp/types.go

Length of output: 266


Pointer handling in RequestContext constructor is correct

The ProgressToken type is declared as type ProgressToken any (an interface alias), not a pointer. As a result, taking the address of requestParamMeta.ProgressToken produces a *mcp.ProgressToken that exactly matches the progressToken *mcp.ProgressToken field on RequestContext. No double-pointer is introduced, and dereferencing *exchange.progressToken at line 76 is safe.

client/sse_test.go (1)

519-540: Good test coverage for notification filtering.

The test properly verifies that logging notifications are filtered based on the client's log level, ensuring only error-level messages are received when the level is set to warning.

README.md (1)

534-567: Excellent documentation for new RequestContext feature.

The documentation clearly explains the purpose and usage of RequestContext with practical examples. This will help developers understand how to use the notification capabilities effectively.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

546-546: Hard tabs
Column: 1

(MD010, no-hard-tabs)


547-547: Hard tabs
Column: 1

(MD010, no-hard-tabs)


548-548: Hard tabs
Column: 1

(MD010, no-hard-tabs)


549-549: Hard tabs
Column: 1

(MD010, no-hard-tabs)


550-550: Hard tabs
Column: 1

(MD010, no-hard-tabs)


552-552: Hard tabs
Column: 1

(MD010, no-hard-tabs)


553-553: Hard tabs
Column: 1

(MD010, no-hard-tabs)


554-554: Hard tabs
Column: 1

(MD010, no-hard-tabs)


555-555: Hard tabs
Column: 1

(MD010, no-hard-tabs)


557-557: Hard tabs
Column: 1

(MD010, no-hard-tabs)


558-558: Hard tabs
Column: 1

(MD010, no-hard-tabs)


559-559: Hard tabs
Column: 1

(MD010, no-hard-tabs)


560-560: Hard tabs
Column: 1

(MD010, no-hard-tabs)


561-561: Hard tabs
Column: 1

(MD010, no-hard-tabs)


562-562: Hard tabs
Column: 1

(MD010, no-hard-tabs)


563-563: Hard tabs
Column: 1

(MD010, no-hard-tabs)


564-564: Hard tabs
Column: 1

(MD010, no-hard-tabs)

examples/everything/main.go (1)

194-194: Consistent handler signature updates.

All handler function signatures have been properly updated to include the requestContext server.RequestContext parameter. This maintains consistency across the codebase and enables the new notification capabilities.

Also applies to: 208-208, 222-222, 260-260, 279-279, 318-318, 338-338, 360-360, 391-391, 457-457

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
client/sse_test.go (3)

71-109: Well-implemented notification testing handler with minor optimization opportunity.

The handler correctly demonstrates both progress and logging notifications. The implementation properly:

  • Sends progress notifications with start/end messages
  • Tests log level filtering by sending both INFO and ERROR level messages
  • Handles errors from notification sending
  • Uses proper progress token handling

Consider extracting the common notification testing logic into a helper function to reduce code duplication across handlers:

+func sendTestNotifications(ctx context.Context, requestContext server.RequestContext, operation string) error {
+	totalProgressValue := float64(100)
+	startMessage := fmt.Sprintf("start %s", operation)
+	
+	if err := requestContext.SendProgressNotification(ctx, float64(0), &totalProgressValue, &startMessage); err != nil {
+		return err
+	}
+	
+	if err := requestContext.SendLoggingNotification(ctx, mcp.LoggingLevelInfo, map[string]any{
+		"filtered_log_message": "will be filtered by log level",
+	}); err != nil {
+		return err
+	}
+	
+	if err := requestContext.SendLoggingNotification(ctx, mcp.LoggingLevelError, map[string]any{
+		"log_message": "log message value",
+	}); err != nil {
+		return err
+	}
+	
+	endMessage := fmt.Sprintf("end %s", operation)
+	return requestContext.SendProgressNotification(ctx, float64(100), &totalProgressValue, &endMessage)
+}

602-693: Comprehensive prompt notification test with debugging statement.

The test properly verifies prompt notifications, but contains a debugging print statement that should be removed.

Remove the debugging print statement:

-		println(fmt.Sprintf("%v", result))

464-477: Consider extracting common notification test setup.

The notification handling setup is duplicated across multiple test cases. Consider extracting this into a helper function to reduce code duplication and improve maintainability.

+func setupNotificationHandling() (*sync.Mutex, *int, **mcp.JSONRPCNotification, *[]*mcp.JSONRPCNotification, func(mcp.JSONRPCNotification)) {
+	mu := &sync.Mutex{}
+	notificationNum := 0
+	var messageNotification *mcp.JSONRPCNotification
+	progressNotifications := make([]*mcp.JSONRPCNotification, 0)
+	
+	handler := func(notification mcp.JSONRPCNotification) {
+		mu.Lock()
+		defer mu.Unlock()
+		if notification.Method == string(mcp.MethodNotificationMessage) {
+			messageNotification = &notification
+		} else if notification.Method == string(mcp.MethodNotificationProgress) {
+			progressNotifications = append(progressNotifications, &notification)
+		}
+		notificationNum++
+	}
+	
+	return mu, &notificationNum, &messageNotification, &progressNotifications, handler
+}

Also applies to: 554-560, 608-621, 701-714

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fc3c83 and 8b0fffa.

📒 Files selected for processing (2)
  • client/sse_test.go (6 hunks)
  • server/sse.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/sse.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (8)
client/sse_test.go (8)

5-8: LGTM! Proper imports added for new functionality.

The import additions are appropriate for the new notification testing functionality:

  • fmt for formatted output in tests
  • assert from testify for improved test assertions
  • sync for mutex-based synchronization in concurrent notification handling

33-33: LGTM! Logging capability properly enabled.

The server is correctly configured with logging capability using server.WithLogging(), which is necessary for testing log notifications.


46-46: LGTM! Handler signatures updated to include RequestContext.

The handler function signatures have been correctly updated to include the server.RequestContext parameter, which enables sending notifications to clients. This aligns with the broader codebase changes mentioned in the AI summary.

Also applies to: 59-59


110-151: Consistent notification implementation for prompt handler.

The prompt handler follows the same notification pattern as the tool handler, which is good for consistency. The implementation correctly sends progress and logging notifications.


153-189: Consistent notification implementation for resource handler.

The resource handler maintains the same notification pattern, ensuring consistent behavior across all handler types.


458-546: Comprehensive test case with proper synchronization.

The test case properly:

  • Uses mutex for thread-safe notification handling
  • Sets up notification callback before starting operations
  • Tests log level filtering (INFO filtered out, ERROR received)
  • Verifies progress notifications with correct token and values
  • Uses proper assertions for all notification fields

548-600: Good test case for verifying notification filtering.

This test correctly verifies that when logging level is set to CRITICAL, lower-level notifications (INFO/ERROR) are filtered out, and progress notifications are not sent when no progress token is provided.


695-785: Well-structured resource notification test.

The test case for resource notifications follows the same comprehensive pattern as the other notification tests, properly verifying all aspects of the notification system.

@dugenkui03 dugenkui03 force-pushed the support-RequestContext-with-logging-progress-cancellation branch from 8b0fffa to f06b092 Compare May 25, 2025 20:04
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
client/sse_test.go (1)

458-546: ⚠️ Potential issue

Fix critical mutex issue - double lock detected.

The test has excellent notification coverage but contains a critical synchronization bug.

-		mu.Lock()
+		mu.Unlock()

This double lock at line 545 can cause deadlocks. The mutex should be unlocked to properly release the lock acquired at line 523.

🧹 Nitpick comments (1)
client/sse_test.go (1)

668-668: Remove debug println statement.

The println statement should be removed from production test code.

-		println(fmt.Sprintf("%v", result))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b0fffa and f06b092.

📒 Files selected for processing (2)
  • client/sse_test.go (6 hunks)
  • server/sse.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/sse.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (8)
client/sse_test.go (8)

5-8: LGTM - Appropriate imports for notification testing.

The added imports support the new notification testing functionality with proper synchronization and assertions.


33-33: LGTM - Enable logging capabilities for notification testing.

Adding server.WithLogging() is necessary to support the logging notification features being tested.


46-46: LGTM - Handler signature updates align with new RequestContext API.

The addition of requestContext server.RequestContext parameter enables handlers to send notifications to clients, which is essential for the new feature.

Also applies to: 59-59


71-109: LGTM - Comprehensive notification testing tool.

The implementation provides excellent coverage of notification features:

  • Progress notifications with proper progress tracking (0% → 100%)
  • Logging notifications at different levels for filter testing
  • Proper error handling for notification failures

This tool effectively validates the notification capabilities.


110-151: LGTM - Consistent notification pattern across operation types.

The prompt handler implements the same notification pattern as the tool handler, ensuring comprehensive testing of notification support across all MCP operation types.


153-189: LGTM - Completes notification testing coverage.

The resource handler implements consistent notification patterns, completing comprehensive test coverage across all MCP operation types (tools, prompts, resources).


548-600: LGTM - Important negative testing for notification filtering.

This test ensures notifications are only sent when appropriate (with progress token) and demonstrates proper logging level filtering. The mutex usage is correct here.


695-785: LGTM - Completes comprehensive notification testing suite.

This test validates notification support for resource operations, completing thorough coverage across all MCP operation types with proper assertions and synchronization.

@dugenkui03 dugenkui03 force-pushed the support-RequestContext-with-logging-progress-cancellation branch from f06b092 to 2399b78 Compare May 25, 2025 20:10
@dugenkui03 dugenkui03 force-pushed the support-RequestContext-with-logging-progress-cancellation branch from 2399b78 to c5b90a8 Compare May 25, 2025 20:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
server/request_session.go (1)

118-118: Track the TODO for future implementation.

The TODO indicates plans to implement additional methods like 'roots/list'. Consider creating an issue to track this future work.

Would you like me to create a GitHub issue to track the implementation of additional RequestSession methods?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f06b092 and 7257736.

📒 Files selected for processing (20)
  • README.md (12 hunks)
  • client/inprocess_test.go (3 hunks)
  • client/sse_test.go (6 hunks)
  • examples/custom_context/main.go (1 hunks)
  • examples/dynamic_path/main.go (1 hunks)
  • examples/everything/main.go (10 hunks)
  • examples/typed_tools/main.go (2 hunks)
  • mcptest/mcptest_test.go (1 hunks)
  • server/request_session.go (1 hunks)
  • server/resource_test.go (5 hunks)
  • server/server.go (15 hunks)
  • server/server_race_test.go (7 hunks)
  • server/server_test.go (17 hunks)
  • server/session_test.go (9 hunks)
  • server/sse.go (3 hunks)
  • server/sse_test.go (3 hunks)
  • server/stdio_test.go (1 hunks)
  • server/streamable_http_test.go (2 hunks)
  • server/typed_tools_handler_func.go (1 hunks)
  • server/typed_tools_handler_func_test.go (14 hunks)
🚧 Files skipped from review as they are similar to previous changes (17)
  • examples/typed_tools/main.go
  • server/resource_test.go
  • examples/dynamic_path/main.go
  • examples/custom_context/main.go
  • server/typed_tools_handler_func.go
  • server/sse.go
  • mcptest/mcptest_test.go
  • server/server_race_test.go
  • server/sse_test.go
  • server/stdio_test.go
  • client/inprocess_test.go
  • server/streamable_http_test.go
  • server/server_test.go
  • server/typed_tools_handler_func_test.go
  • server/session_test.go
  • server/server.go
  • examples/everything/main.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
client/sse_test.go (4)
server/server.go (1)
  • WithLogging (265-269)
server/request_session.go (1)
  • RequestSession (13-17)
mcp/types.go (21)
  • LoggingLevelInfo (689-689)
  • LoggingLevelError (692-692)
  • Content (782-784)
  • TextContent (788-793)
  • TextContent (795-795)
  • Resource (590-605)
  • ReadResourceRequest (526-538)
  • ResourceContents (640-642)
  • TextResourceContents (644-652)
  • TextResourceContents (654-654)
  • JSONRPCNotification (333-336)
  • MethodNotificationMessage (73-73)
  • MethodNotificationProgress (77-77)
  • InitializeRequest (384-393)
  • Params (177-177)
  • Implementation (463-466)
  • SetLevelRequest (671-679)
  • LoggingLevelWarning (691-691)
  • Meta (135-147)
  • ProgressToken (128-128)
  • LoggingLevelCritical (693-693)
client/sse.go (1)
  • NewSSEMCPClient (25-33)
🪛 markdownlint-cli2 (0.17.2)
README.md

95-95: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


95-95: Link fragments should be valid
Expected: #requestsession; Actual: #RequestSession

(MD051, link-fragments)


546-546: Hard tabs
Column: 1

(MD010, no-hard-tabs)


547-547: Hard tabs
Column: 1

(MD010, no-hard-tabs)


548-548: Hard tabs
Column: 1

(MD010, no-hard-tabs)


549-549: Hard tabs
Column: 1

(MD010, no-hard-tabs)


550-550: Hard tabs
Column: 1

(MD010, no-hard-tabs)


552-552: Hard tabs
Column: 1

(MD010, no-hard-tabs)


553-553: Hard tabs
Column: 1

(MD010, no-hard-tabs)


554-554: Hard tabs
Column: 1

(MD010, no-hard-tabs)


555-555: Hard tabs
Column: 1

(MD010, no-hard-tabs)


557-557: Hard tabs
Column: 1

(MD010, no-hard-tabs)


558-558: Hard tabs
Column: 1

(MD010, no-hard-tabs)


559-559: Hard tabs
Column: 1

(MD010, no-hard-tabs)


560-560: Hard tabs
Column: 1

(MD010, no-hard-tabs)


561-561: Hard tabs
Column: 1

(MD010, no-hard-tabs)


562-562: Hard tabs
Column: 1

(MD010, no-hard-tabs)


563-563: Hard tabs
Column: 1

(MD010, no-hard-tabs)


564-564: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (3)
server/request_session.go (1)

1-118: Well-structured implementation of RequestSession!

The RequestSession provides a clean interface for sending notifications to clients. The capability checks and error handling are properly implemented.

client/sse_test.go (2)

70-108: Comprehensive test handlers for notification functionality!

The handlers correctly demonstrate sending both progress and logging notifications at different log levels. Good test coverage for the RequestSession functionality.

Also applies to: 109-150, 152-188


457-546: Excellent test coverage for notification scenarios!

The test cases thoroughly validate:

  • Progress notifications with tokens
  • Log level filtering
  • Notification content and metadata
  • Edge cases where notifications should not be sent

The use of mutexes for thread-safe notification collection is appropriate.

Also applies to: 548-600, 602-690, 692-782

@dugenkui03 dugenkui03 force-pushed the support-RequestContext-with-logging-progress-cancellation branch from 7257736 to ef53de3 Compare May 26, 2025 05:32
@dugenkui03 dugenkui03 force-pushed the support-RequestContext-with-logging-progress-cancellation branch from ef53de3 to 51fbd1d Compare May 26, 2025 05:33
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

♻️ Duplicate comments (2)
README.md (2)

95-95: Fix anchor link case mismatch.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

95-95: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


95-95: Link fragments should be valid
Expected: #requestsession; Actual: #requestSession

(MD051, link-fragments)


534-567: Fix formatting and typo issues in RequestSession section.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

546-546: Hard tabs
Column: 1

(MD010, no-hard-tabs)


547-547: Hard tabs
Column: 1

(MD010, no-hard-tabs)


548-548: Hard tabs
Column: 1

(MD010, no-hard-tabs)


549-549: Hard tabs
Column: 1

(MD010, no-hard-tabs)


550-550: Hard tabs
Column: 1

(MD010, no-hard-tabs)


552-552: Hard tabs
Column: 1

(MD010, no-hard-tabs)


553-553: Hard tabs
Column: 1

(MD010, no-hard-tabs)


554-554: Hard tabs
Column: 1

(MD010, no-hard-tabs)


555-555: Hard tabs
Column: 1

(MD010, no-hard-tabs)


557-557: Hard tabs
Column: 1

(MD010, no-hard-tabs)


558-558: Hard tabs
Column: 1

(MD010, no-hard-tabs)


559-559: Hard tabs
Column: 1

(MD010, no-hard-tabs)


560-560: Hard tabs
Column: 1

(MD010, no-hard-tabs)


561-561: Hard tabs
Column: 1

(MD010, no-hard-tabs)


562-562: Hard tabs
Column: 1

(MD010, no-hard-tabs)


563-563: Hard tabs
Column: 1

(MD010, no-hard-tabs)


564-564: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🧹 Nitpick comments (3)
client/sse_test.go (3)

70-108: Consider refactoring duplicated notification logic.

The notification sending logic (progress + logging) is repeated across multiple handlers. Consider extracting this into a helper function to reduce code duplication.

Example helper function:

func sendTestNotifications(ctx context.Context, requestSession server.RequestSession, prefix string) error {
    totalProgressValue := float64(100)
    startMessage := fmt.Sprintf("start %s", prefix)
    
    if err := requestSession.SendProgressNotification(ctx, float64(0), &totalProgressValue, &startMessage); err != nil {
        return err
    }

    if err := requestSession.SendLoggingNotification(ctx, mcp.LoggingLevelInfo, map[string]any{
        "filtered_log_message": "will be filtered by log level",
    }); err != nil {
        return err
    }
    
    if err := requestSession.SendLoggingNotification(ctx, mcp.LoggingLevelError, map[string]any{
        "log_message": "log message value",
    }); err != nil {
        return err
    }

    endMessage := fmt.Sprintf("end %s", prefix)
    return requestSession.SendProgressNotification(ctx, float64(100), &totalProgressValue, &endMessage)
}

457-546: Test implementation looks robust but could benefit from helper functions.

The test correctly:

  • Uses proper synchronization with mutex
  • Sets up notification handlers before starting client
  • Validates notification content and metadata
  • Uses appropriate timeouts

However, this test pattern is repeated multiple times. Consider extracting common setup/assertion logic into helper functions.

Example helper functions:

func setupNotificationClient(t *testing.T, serverURL string) (*client.SSEMCPClient, *sync.Mutex, *int, **mcp.JSONRPCNotification, *[]*mcp.JSONRPCNotification) {
    client, err := NewSSEMCPClient(serverURL + "/sse")
    require.NoError(t, err)
    
    mu := &sync.Mutex{}
    notificationNum := 0
    var messageNotification *mcp.JSONRPCNotification
    progressNotifications := make([]*mcp.JSONRPCNotification, 0)
    
    client.OnNotification(func(notification mcp.JSONRPCNotification) {
        mu.Lock()
        defer mu.Unlock()
        if notification.Method == string(mcp.MethodNotificationMessage) {
            messageNotification = &notification
        } else if notification.Method == string(mcp.MethodNotificationProgress) {
            progressNotifications = append(progressNotifications, &notification)
        }
        notificationNum++
    })
    
    return client, mu, &notificationNum, &messageNotification, &progressNotifications
}

func assertNotifications(t *testing.T, mu *sync.Mutex, notificationNum int, messageNotification *mcp.JSONRPCNotification, progressNotifications []*mcp.JSONRPCNotification, expectedStartMsg, expectedEndMsg string) {
    mu.Lock()
    defer mu.Unlock()
    
    assert.Equal(t, 3, notificationNum)
    assert.NotNil(t, messageNotification)
    assert.Equal(t, string(mcp.MethodNotificationMessage), messageNotification.Method)
    assert.Equal(t, "error", messageNotification.Params.AdditionalFields["level"])
    assert.Equal(t, map[string]any{"log_message": "log message value"}, messageNotification.Params.AdditionalFields["data"])
    
    assert.Len(t, progressNotifications, 2)
    
    // First progress notification
    assert.Equal(t, string(mcp.MethodNotificationProgress), progressNotifications[0].Method)
    assert.Equal(t, expectedStartMsg, progressNotifications[0].Params.AdditionalFields["message"])
    assert.EqualValues(t, 0, progressNotifications[0].Params.AdditionalFields["progress"])
    assert.Equal(t, "progress_token", progressNotifications[0].Params.AdditionalFields["progressToken"])
    assert.EqualValues(t, 100, progressNotifications[0].Params.AdditionalFields["total"])
    
    // Second progress notification  
    assert.Equal(t, string(mcp.MethodNotificationProgress), progressNotifications[1].Method)
    assert.Equal(t, expectedEndMsg, progressNotifications[1].Params.AdditionalFields["message"])
    assert.EqualValues(t, 100, progressNotifications[1].Params.AdditionalFields["progress"])
    assert.Equal(t, "progress_token", progressNotifications[1].Params.AdditionalFields["progressToken"])
    assert.EqualValues(t, 100, progressNotifications[1].Params.AdditionalFields["total"])
}

520-520: Consider reducing sleep duration for faster test execution.

The 500ms sleep might be unnecessarily long for notification processing. Consider reducing to 100-200ms or using a more deterministic approach with channels/waitgroups.

-time.Sleep(time.Millisecond * 500)
+time.Sleep(time.Millisecond * 100)

Also applies to: 596-596, 666-666, 758-758

🛑 Comments failed to post (1)
README.md (1)

534-567: 🛠️ Refactor suggestion

Verify RequestSession example accuracy.

The example code references testHeaderKey and testHeaderFuncKey which are not defined in the context of this example. This might confuse readers since these variables aren't available in a typical implementation.

Consider updating the example to be more self-contained:

 return &mcp.CallToolResult{
     Content: []mcp.Content{
         mcp.TextContent{
             Type: "text",
-            Text: "context from header: " + ctx.Value(testHeaderKey).(string) + ", " + ctx.Value(testHeaderFuncKey).(string),
+            Text: "RequestSession notification example completed successfully",
         },
     },
 }, nil
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

return &mcp.CallToolResult{
    Content: []mcp.Content{
        mcp.TextContent{
            Type: "text",
            Text: "RequestSession notification example completed successfully",
        },
    },
}, nil
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

546-546: Hard tabs
Column: 1

(MD010, no-hard-tabs)


547-547: Hard tabs
Column: 1

(MD010, no-hard-tabs)


548-548: Hard tabs
Column: 1

(MD010, no-hard-tabs)


549-549: Hard tabs
Column: 1

(MD010, no-hard-tabs)


550-550: Hard tabs
Column: 1

(MD010, no-hard-tabs)


552-552: Hard tabs
Column: 1

(MD010, no-hard-tabs)


553-553: Hard tabs
Column: 1

(MD010, no-hard-tabs)


554-554: Hard tabs
Column: 1

(MD010, no-hard-tabs)


555-555: Hard tabs
Column: 1

(MD010, no-hard-tabs)


557-557: Hard tabs
Column: 1

(MD010, no-hard-tabs)


558-558: Hard tabs
Column: 1

(MD010, no-hard-tabs)


559-559: Hard tabs
Column: 1

(MD010, no-hard-tabs)


560-560: Hard tabs
Column: 1

(MD010, no-hard-tabs)


561-561: Hard tabs
Column: 1

(MD010, no-hard-tabs)


562-562: Hard tabs
Column: 1

(MD010, no-hard-tabs)


563-563: Hard tabs
Column: 1

(MD010, no-hard-tabs)


564-564: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🤖 Prompt for AI Agents
In README.md around lines 534 to 567, the example code for RequestSession uses
undefined variables testHeaderKey and testHeaderFuncKey, which can confuse
readers. Replace these variables with either defined constants or remove the
context.Value calls to make the example self-contained and clear. Ensure the
example compiles and runs independently without relying on external undefined
variables.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (4)
server/request_session.go (4)

13-15: Consider expanding the struct for future extensibility

The struct currently only holds a progress token, but given the TODO comment about implementing other methods like 'roots/list', consider adding fields that might be needed for future session features.


29-32: Improve receiver variable naming for consistency

The receiver variable exchange doesn't match the struct name RequestSession. Consider using rs or session for better clarity.

-func (exchange *RequestSession) IsLoggingNotificationSupported(ctx context.Context) bool {
+func (rs *RequestSession) IsLoggingNotificationSupported(ctx context.Context) bool {

67-89: Good progress notification implementation with minor improvements

The method correctly checks for progress token presence. Consider adding input validation and fixing the receiver variable name.

-func (exchange *RequestSession) SendProgressNotification(ctx context.Context, progress float64, total *float64, message *string) error {
-	if exchange.progressToken == nil {
+func (rs *RequestSession) SendProgressNotification(ctx context.Context, progress float64, total *float64, message *string) error {
+	if progress < 0 {
+		return fmt.Errorf("progress cannot be negative")
+	}
+	if total != nil && *total < 0 {
+		return fmt.Errorf("total cannot be negative")
+	}
+	
+	if rs.progressToken == nil {
 		return nil
 	}
 
 	params := map[string]any{
 		"progress":      progress,
-		"progressToken": *exchange.progressToken,
+		"progressToken": *rs.progressToken,
 	}

118-118: Address the TODO comment for completeness

The TODO comment suggests implementing additional methods like 'roots/list'. Consider creating issues to track these future enhancements or implement them as part of this PR if they're needed for the current feature.

Would you like me to help create a plan for implementing the additional methods mentioned in the TODO comment?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 51fbd1d and 45d7713.

📒 Files selected for processing (2)
  • server/request_session.go (1 hunks)
  • server/server.go (15 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/server.go
🔇 Additional comments (4)
server/request_session.go (4)

1-7: LGTM: Clean package structure and imports

The package declaration and imports are well-organized and appropriate for the functionality.


9-9: Good use of unexported key type for context

Using an unexported struct type as a context key is a Go best practice that prevents key collisions.


92-116: ⚠️ Potential issue

Fix potential nil pointer dereference in reason parameter

The method has good error handling for request ID validation, but there's an issue with the reason parameter handling on line 107.

-func (exchange *RequestSession) SendCancellationNotification(ctx context.Context, reason *string) error {
+func (rs *RequestSession) SendCancellationNotification(ctx context.Context, reason *string) error {
 	requestIDRawValue := ctx.Value(requestIDKey{})
 	if requestIDRawValue == nil {
 		return fmt.Errorf("invalid requestID")
@@ -104,7 +104,7 @@
 		"requestId": requestID.Value(),
 	}
 	if reason != nil {
-		params["reason"] = reason
+		params["reason"] = *reason
 	}

Likely an incorrect or invalid review comment.


17-26:

✅ Verification successful

Verify progress token pointer handling

The assignment on line 22 takes the address of requestParamMeta.ProgressToken. Ensure this is correct based on the ProgressToken field type in the Meta struct.


🏁 Script executed:

#!/bin/bash
# Check the definition of ProgressToken in the Meta struct
ast-grep --pattern $'type Meta struct {
  $$$
  ProgressToken $_
  $$$
}'

Length of output: 810


🏁 Script executed:

#!/bin/bash
# Locate the ProgressToken type definition
rg -n "^type ProgressToken" -A3 -B3 mcp/types.go

# Locate RequestSession and its progressToken field
rg -n "^type RequestSession" -A5 server/request_session.go
rg -n "progressToken" -C2 server/request_session.go

Length of output: 1496


ProgressToken pointer assignment is correct

We’ve confirmed that ProgressToken is declared as a non‐pointer alias (type ProgressToken any in mcp/types.go:128), so taking its address (&requestParamMeta.ProgressToken) produces a *mcp.ProgressToken that exactly matches the progressToken *mcp.ProgressToken field in RequestSession. No changes are required.

@dugenkui03 dugenkui03 marked this pull request as draft May 28, 2025 16:51
@dugenkui03 dugenkui03 marked this pull request as ready for review May 28, 2025 16:58
@pottekkat
Copy link
Collaborator

@dugenkui03 Can you resolve the conflicts?

@dugenkui03
Copy link
Collaborator Author

@dugenkui03 Can you resolve the conflicts?

@pottekkat conflicts are fixed

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 45d7713 and 5f32b4d.

📒 Files selected for processing (4)
  • mcp/prompts.go (1 hunks)
  • mcp/types.go (3 hunks)
  • server/server.go (15 hunks)
  • server/server_test.go (17 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • mcp/prompts.go
  • server/server.go
  • server/server_test.go
🔇 Additional comments (3)
mcp/types.go (3)

59-69: LGTM: Good type safety improvement for existing notification constants.

The explicit typing of existing notification method constants as MCPMethod improves type safety and consistency. This is a good refactoring practice.


71-93: LGTM: Well-documented new notification method constants.

The three new notification method constants are properly documented with comprehensive comments and specification links. The naming follows the established pattern and the protocol semantics are clearly explained.


602-605: LGTM: Consistent metadata field addition.

Adding the Meta field to ReadResourceParams aligns with the protocol's metadata support and is consistent with similar additions mentioned in other parts of the codebase.

Comment on lines +790 to +812
var (
levelToSeverity = func() map[LoggingLevel]int {
return map[LoggingLevel]int{
LoggingLevelEmergency: 0,
LoggingLevelAlert: 1,
LoggingLevelCritical: 2,
LoggingLevelError: 3,
LoggingLevelWarning: 4,
LoggingLevelNotice: 5,
LoggingLevelInfo: 6,
LoggingLevelDebug: 7,
}
}()
)

// Allows is a helper function that decides a message could be sent to client or not according to the logging level
func (subscribedLevel LoggingLevel) Allows(currentLevel LoggingLevel) (bool, error) {
if _, ok := levelToSeverity[currentLevel]; !ok {
return false, fmt.Errorf("illegal message logging level:%s", currentLevel)
}
return levelToSeverity[subscribedLevel] >= levelToSeverity[currentLevel], nil
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix potential bug in logging level validation.

The Allows method has a logical flaw: it only validates that currentLevel exists in the map but doesn't validate subscribedLevel. If an invalid subscribedLevel is passed, the map lookup returns 0 (Emergency severity), which would incorrectly allow all messages.

Apply this fix to validate both logging levels:

-func (subscribedLevel LoggingLevel) Allows(currentLevel LoggingLevel) (bool, error) {
-	if _, ok := levelToSeverity[currentLevel]; !ok {
-		return false, fmt.Errorf("illegal message logging level:%s", currentLevel)
-	}
-	return levelToSeverity[subscribedLevel] >= levelToSeverity[currentLevel], nil
-}
+func (subscribedLevel LoggingLevel) Allows(currentLevel LoggingLevel) (bool, error) {
+	if _, ok := levelToSeverity[currentLevel]; !ok {
+		return false, fmt.Errorf("illegal message logging level: %s", currentLevel)
+	}
+	if _, ok := levelToSeverity[subscribedLevel]; !ok {
+		return false, fmt.Errorf("illegal subscribed logging level: %s", subscribedLevel)
+	}
+	return levelToSeverity[subscribedLevel] >= levelToSeverity[currentLevel], nil
+}

Note: I also fixed a minor spacing issue in the error message format.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var (
levelToSeverity = func() map[LoggingLevel]int {
return map[LoggingLevel]int{
LoggingLevelEmergency: 0,
LoggingLevelAlert: 1,
LoggingLevelCritical: 2,
LoggingLevelError: 3,
LoggingLevelWarning: 4,
LoggingLevelNotice: 5,
LoggingLevelInfo: 6,
LoggingLevelDebug: 7,
}
}()
)
// Allows is a helper function that decides a message could be sent to client or not according to the logging level
func (subscribedLevel LoggingLevel) Allows(currentLevel LoggingLevel) (bool, error) {
if _, ok := levelToSeverity[currentLevel]; !ok {
return false, fmt.Errorf("illegal message logging level:%s", currentLevel)
}
return levelToSeverity[subscribedLevel] >= levelToSeverity[currentLevel], nil
}
func (subscribedLevel LoggingLevel) Allows(currentLevel LoggingLevel) (bool, error) {
if _, ok := levelToSeverity[currentLevel]; !ok {
return false, fmt.Errorf("illegal message logging level: %s", currentLevel)
}
if _, ok := levelToSeverity[subscribedLevel]; !ok {
return false, fmt.Errorf("illegal subscribed logging level: %s", subscribedLevel)
}
return levelToSeverity[subscribedLevel] >= levelToSeverity[currentLevel], nil
}
🤖 Prompt for AI Agents
In mcp/types.go around lines 790 to 812, the Allows method currently only
validates if currentLevel exists in the levelToSeverity map but does not
validate subscribedLevel, which can cause incorrect behavior if subscribedLevel
is invalid. To fix this, add a check to ensure subscribedLevel is also a valid
key in levelToSeverity before comparing severities. If subscribedLevel is
invalid, return an error similar to the currentLevel validation. Also, correct
the spacing in the error message format for consistency.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🔭 Outside diff range comments (1)
client/http_test.go (1)

32-59: 💡 Verification agent

🧩 Analysis chain

Use the new RequestSession parameter for sending notifications.

The new RequestSession parameter is added but not utilized. The handler still uses the old server.SendNotificationToClient method instead of leveraging the session-based approach. This defeats the purpose of introducing the session parameter.

Based on the PR objectives to support log/cancelled/progress notifications, consider updating the implementation to use the session parameter:

 		func(
 			ctx context.Context,
-			requestionSession server.RequestSession,
+			requestSession server.RequestSession,
 			request mcp.CallToolRequest,
 		) (*mcp.CallToolResult, error) {
-			server := server.ServerFromContext(ctx)
-			err := server.SendNotificationToClient(
-				ctx,
-				"notifications/progress",
-				map[string]any{
-					"progress":      10,
-					"total":         10,
-					"progressToken": 0,
-				},
-			)
+			err := requestSession.SendProgress(10, 10)
 			if err != nil {
 				return nil, fmt.Errorf("failed to send notification: %w", err)
 			}

Let me verify the available methods on the RequestSession struct:


🏁 Script executed:

#!/bin/bash
# Description: Check the available methods on RequestSession struct
# Expected: Methods for sending progress, log, and cancellation notifications

ast-grep --pattern $'type RequestSession struct {
  $$$
}'

ast-grep --pattern $'func ($_ *RequestSession) $FUNC_NAME($$$) $$$'

Length of output: 4746


Replace direct Server.SendNotificationToClient with RequestSession.SendProgressNotification

The test handler still calls ServerFromContext(...).SendNotificationToClient instead of using the injected RequestSession. Update it to:

  • Rename the parameter from requestionSessionrequestSession.
  • Remove the server := ServerFromContext(ctx) lookup and its SendNotificationToClient call.
  • Call requestSession.SendProgressNotification(ctx, progress, &total, nil) to send progress via the session.

client/http_test.go (around lines 32–59):

-   func(
-       ctx context.Context,
-       requestionSession server.RequestSession,
-       request mcp.CallToolRequest,
-   ) (*mcp.CallToolResult, error) {
-       server := server.ServerFromContext(ctx)
-       err := server.SendNotificationToClient(
-           ctx,
-           "notifications/progress",
-           map[string]any{
-               "progress":      10,
-               "total":         10,
-               "progressToken": 0,
-           },
-       )
+   func(
+       ctx context.Context,
+       requestSession server.RequestSession,
+       request mcp.CallToolRequest,
+   ) (*mcp.CallToolResult, error) {
+       total := 10.0
+       err := requestSession.SendProgressNotification(ctx, 10, &total, nil)
        if err != nil {
            return nil, fmt.Errorf("failed to send notification: %w", err)
        }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f32b4d and 8bf9e7a.

📒 Files selected for processing (3)
  • client/http_test.go (1 hunks)
  • server/session.go (1 hunks)
  • server/streamable_http.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • server/session.go
  • server/streamable_http.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
client/http_test.go (1)
server/request_session.go (1)
  • RequestSession (13-15)

Copy link
Collaborator

@pottekkat pottekkat left a comment

Choose a reason for hiding this comment

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

I think the higher level design is good as described in the linked issue.

But, SDK this is a huge breaking change requiring users to change all handlers.

Also, can we make the session capabilities available through the context itself? That would not require any change to existing users, will add the capability and is more idiomatic Go.

That seems like the more elegant approach. Maybe you have already considered this and can give more input as to why you think the current solution is better.

@dugenkui03
Copy link
Collaborator Author

@pottekkat thanks for your review. I will convert this PR to draft first, and will reopen it once I have completed update.

@dugenkui03 dugenkui03 marked this pull request as draft June 6, 2025 02:03
@pottekkat
Copy link
Collaborator

Ok @dugenkui03 Thank you for seeing this through.

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.

feature: Support log/cancelled/progress notification
2 participants