Skip to content

Implement sampling in Stdio #461

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 8, 2025
Merged

Implement sampling in Stdio #461

merged 12 commits into from
Jul 8, 2025

Conversation

ezynda3
Copy link
Contributor

@ezynda3 ezynda3 commented Jun 29, 2025

Description

Fixes #<issue_number> (if applicable)

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

  • New Features

    • Added support for bidirectional sampling requests, enabling servers to request LLM completions from clients and clients to respond with generated content.
    • Introduced a configurable sampling handler interface for clients to process sampling requests.
    • Enhanced server and client initialization to automatically declare sampling capability when supported.
    • Provided example implementations and usage for both sampling-enabled clients and servers.
  • Documentation

    • Added comprehensive guides and examples for implementing sampling on both clients and servers.
    • Updated documentation to highlight advanced sampling features and best practices.
    • Expanded sidebar and navigation to include new advanced sampling sections.
  • Bug Fixes

    • Improved error handling and response routing for server-to-client sampling requests and responses.
  • Tests

    • Introduced extensive unit tests for sampling functionality on both client and server sides to ensure correct behavior and integration.
  • Chores

    • Updated configuration to reflect new advanced sampling documentation in the sidebar.

Copy link
Contributor

coderabbitai bot commented Jun 29, 2025

Walkthrough

This change introduces full support for MCP sampling in both the client and server. It adds a bidirectional sampling handler to the client, enabling it to process sampling requests from servers. The server is updated to send sampling requests and handle asynchronous responses. Documentation and example implementations are included.

Changes

Files/Paths Change Summary
client/client.go, client/sampling.go, client/sampling_test.go Added sampling handler interface and integration in the client, including bidirectional request handling and related tests.
client/transport/interface.go, client/transport/stdio.go Introduced bidirectional transport interface, request handler registration, and response routing for server-initiated requests.
client/transport/stdio_test.go Updated notification test to accommodate new notification handling logic.
examples/sampling_client/README.md, examples/sampling_client/main.go Added example client with sampling handler implementation and usage instructions.
examples/sampling_server/README.md, examples/sampling_server/main.go Added example server supporting sampling requests and tool integration.
mcp/types.go Added new constant for the sampling request method.
server/sampling.go, server/sampling_test.go Added server-side sampling support, request forwarding, and tests for sampling scenarios.
server/stdio.go Implemented asynchronous sampling request/response handling in stdio session.
www/docs/pages/clients/advanced-sampling.mdx, www/docs/pages/clients/operations.mdx Added documentation for implementing and using client-side sampling.
www/docs/pages/servers/advanced-sampling.mdx, www/docs/pages/servers/advanced.mdx Added documentation for enabling and using server-side sampling.
www/docs/pages/servers/index.mdx Updated server documentation to mention sampling as an advanced feature.
www/vocs.config.ts Added sidebar entries for advanced client and server sampling documentation.

Possibly related issues

  • Feature: Add Sampling Support #419: Implements the MCP sampling feature across client and server, matching the described code changes for sampling support.
  • Implement sampling #6: Implements the protocol and user interaction model for sampling, corresponding to the newly added sampling functionality.

Suggested labels

type: enhancement, area: mcp spec

Suggested reviewers

  • rwjblue-glean
  • pottekkat
  • dugenkui03

📜 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 5217217 and 108b023.

📒 Files selected for processing (2)
  • server/sampling.go (1 hunks)
  • server/sampling_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • server/sampling_test.go
  • server/sampling.go
⏰ 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). (1)
  • GitHub Check: test
✨ 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.

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: 6

🧹 Nitpick comments (5)
client/transport/stdio_test.go (1)

151-151: Track and prioritize fixing the skipped test.

While it's reasonable to skip this test if it's unrelated to the current sampling changes, the notification parsing issue should be tracked and fixed promptly to maintain test coverage.

Would you like me to help investigate the notification parsing issue or create a tracking issue for this TODO?

examples/sampling_client/README.md (1)

1-87: Comprehensive and well-structured documentation.

The README provides excellent documentation covering all important aspects of the sampling client example, including features, usage instructions, and implementation details.

Fix fenced code block language specification.

The static analysis tool correctly identifies a missing language specification for the fenced code block.

-```
+```text
 Connected to server: sampling-example-server v1.0.0
 Available tools:
   - ask_llm: Ask the LLM a question using sampling
   - greet: Greet the user

 --- Testing greet tool ---
 Greet result: Hello, Sampling Demo User! This server supports sampling - try using the ask_llm tool!

 --- Testing ask_llm tool (with sampling) ---
 Mock LLM received: What is the capital of France?
 System prompt: You are a helpful geography assistant.
 Max tokens: 1000
 Temperature: 0.700000
 Ask LLM result: LLM Response (model: mock-llm-v1): Mock LLM response to: 'What is the capital of France?'. This is a simulated response from a mock LLM handler.
-```
+```
client/transport/stdio.go (1)

354-366: Consider improving error handling

Using fmt.Printf for error logging is not ideal in a library context. Errors could be lost or interleaved with application output.

Consider using a configurable logger or error callback:

+// Add to Stdio struct:
+onError func(error)
+
 // sendResponse sends a response back to the server.
-func (c *Stdio) sendResponse(response JSONRPCResponse) {
+func (c *Stdio) sendResponse(response JSONRPCResponse) error {
 	responseBytes, err := json.Marshal(response)
 	if err != nil {
-		fmt.Printf("Error marshaling response: %v\n", err)
-		return
+		return fmt.Errorf("failed to marshal response: %w", err)
 	}
 	responseBytes = append(responseBytes, '\n')
 
 	if _, err := c.stdin.Write(responseBytes); err != nil {
-		fmt.Printf("Error writing response: %v\n", err)
+		return fmt.Errorf("failed to write response: %w", err)
 	}
+	return nil
 }

Then handle the error in handleIncomingRequest with the error callback.

client/client.go (1)

433-479: Consider adding request validation

The implementation is solid, but could benefit from validating the request parameters before processing.

Add parameter validation after unmarshaling:

 	if err := json.Unmarshal(paramsBytes, &params); err != nil {
 		return nil, fmt.Errorf("failed to unmarshal params: %w", err)
 	}
+
+	// Validate required parameters
+	if len(params.Messages) == 0 {
+		return nil, fmt.Errorf("messages cannot be empty")
+	}
+	if params.MaxTokens <= 0 {
+		return nil, fmt.Errorf("maxTokens must be positive")
+	}

This ensures the handler receives valid input and provides better error messages to the server.

server/stdio.go (1)

351-366: Consider tracking concurrent tool call errors

Tool call errors are only logged and not tracked, which could hide failures from monitoring systems.

Consider tracking goroutine completion and errors:

+	// Add to stdioSession struct:
+	activeRequests sync.WaitGroup
+	
 	if json.Unmarshal(rawMessage, &baseMessage) == nil && baseMessage.Method == "tools/call" {
+		s.activeRequests.Add(1)
 		go func() {
+			defer s.activeRequests.Done()
 			response := s.server.HandleMessage(ctx, rawMessage)
 			if response != nil {
 				if err := s.writeResponse(response, writer); err != nil {
 					s.errLogger.Printf("Error writing tool response: %v", err)
+					// Consider incrementing an error metric here
 				}
 			}
 		}()
 		return nil
 	}

This would allow graceful shutdown by waiting for active requests to complete.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1eddde7 and 17ca8df.

📒 Files selected for processing (15)
  • client/client.go (6 hunks)
  • client/sampling.go (1 hunks)
  • client/sampling_test.go (1 hunks)
  • client/transport/interface.go (2 hunks)
  • client/transport/stdio.go (4 hunks)
  • client/transport/stdio_test.go (2 hunks)
  • examples/sampling_client/README.md (1 hunks)
  • examples/sampling_client/main.go (1 hunks)
  • examples/sampling_server/README.md (1 hunks)
  • examples/sampling_server/main.go (1 hunks)
  • mcp/types.go (1 hunks)
  • server/sampling.go (1 hunks)
  • server/sampling_test.go (1 hunks)
  • server/server.go (2 hunks)
  • server/stdio.go (6 hunks)
🧰 Additional context used
🧠 Learnings (7)
client/transport/stdio_test.go (1)
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
client/transport/interface.go (2)
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
examples/sampling_server/README.md (1)
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
examples/sampling_client/main.go (3)
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
examples/sampling_server/main.go (6)
Learnt from: floatingIce91
PR: mark3labs/mcp-go#401
File: server/server.go:1082-1092
Timestamp: 2025-06-23T11:10:42.948Z
Learning: In Go MCP server, ServerTool.Tool field is only used for tool listing and indexing, not for tool execution or middleware. During handleToolCall, only the Handler field is used, so dynamic tools don't need the Tool field populated.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in mark3labs/mcp-go handles both InputSchema and RawInputSchema formats. When unmarshaling JSON, it first tries to parse into a structured ToolInputSchema format, and if that fails, it falls back to using the raw schema format, providing symmetry with the MarshalJSON method.
Learnt from: davidleitw
PR: mark3labs/mcp-go#451
File: mcp/tools.go:1192-1217
Timestamp: 2025-06-26T09:38:18.629Z
Learning: In mcp-go project, the maintainer prefers keeping builder pattern APIs simple without excessive validation for edge cases. The WithOutput* functions are designed to assume correct usage rather than defensive programming, following the principle of API simplicity over comprehensive validation.
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
server/sampling_test.go (1)
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
client/sampling_test.go (1)
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
🧬 Code Graph Analysis (6)
client/transport/stdio_test.go (1)
mcp/types.go (1)
  • Params (162-162)
client/sampling.go (1)
mcp/types.go (2)
  • CreateMessageRequest (775-778)
  • CreateMessageResult (795-802)
client/transport/interface.go (2)
mcp/types.go (3)
  • JSONRPCRequest (310-315)
  • JSONRPCResponse (324-328)
  • Result (231-235)
testdata/mockstdio_server.go (2)
  • JSONRPCRequest (13-18)
  • JSONRPCResponse (20-28)
server/stdio.go (3)
mcp/types.go (8)
  • JSONRPCNotification (318-321)
  • CreateMessageResult (795-802)
  • CreateMessageRequest (775-778)
  • Params (162-162)
  • CreateMessageParams (780-789)
  • JSONRPC_VERSION (108-108)
  • MethodSamplingCreateMessage (768-768)
  • Result (231-235)
server/session.go (2)
  • ClientSession (11-20)
  • SessionWithClientInfo (43-49)
server/sampling.go (1)
  • SessionWithSampling (53-56)
client/transport/stdio.go (2)
client/transport/interface.go (3)
  • RequestHandler (35-35)
  • JSONRPCRequest (47-52)
  • JSONRPCResponse (54-63)
mcp/types.go (5)
  • JSONRPCRequest (310-315)
  • JSONRPCResponse (324-328)
  • JSONRPC_VERSION (108-108)
  • METHOD_NOT_FOUND (350-350)
  • INTERNAL_ERROR (352-352)
client/client.go (4)
client/sampling.go (1)
  • SamplingHandler (11-20)
client/transport/interface.go (3)
  • BidirectionalInterface (39-45)
  • JSONRPCRequest (47-52)
  • JSONRPCResponse (54-63)
mcp/types.go (9)
  • Params (162-162)
  • JSONRPCRequest (310-315)
  • JSONRPCResponse (324-328)
  • MethodSamplingCreateMessage (768-768)
  • CreateMessageParams (780-789)
  • CreateMessageRequest (775-778)
  • Request (153-156)
  • JSONRPC_VERSION (108-108)
  • Result (231-235)
testdata/mockstdio_server.go (2)
  • JSONRPCRequest (13-18)
  • JSONRPCResponse (20-28)
🪛 markdownlint-cli2 (0.17.2)
examples/sampling_client/README.md

54-54: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

🪛 GitHub Check: lint
server/sampling_test.go

[failure] 152-152:
SA5011: possible nil pointer dereference (staticcheck)


[failure] 148-148:
SA5011(related information): this check suggests that the pointer can be nil (staticcheck)

🪛 GitHub Actions: golangci-lint
server/sampling_test.go

[error] 148-148: golangci-lint (staticcheck): SA5011 - this check suggests that the pointer can be nil

🔇 Additional comments (32)
mcp/types.go (1)

766-769: LGTM! Clean constant addition for sampling support.

The new MethodSamplingCreateMessage constant follows the established naming convention and is properly documented. This constant will be used to identify sampling requests in the bidirectional MCP communication.

server/server.go (2)

178-178: Good addition following established capability patterns.

The new sampling field correctly follows the same pointer-based pattern used by other server capabilities (tools, resources, prompts), allowing it to be nil when sampling is not supported.


197-200: Well-structured sampling capabilities definition.

The samplingCapabilities struct is appropriately simple with just an enabled field, which is sufficient for the initial sampling implementation. This follows the established pattern of other capability structs in the codebase.

client/transport/stdio_test.go (1)

185-200: Test logic correctly handles the mock server's notification format.

The updated test logic properly validates that the mock server wraps the original notification in a "debug/test" method and extracts the original method from the params. The JSON marshaling/unmarshaling approach is appropriate for inspecting the notification structure.

client/sampling.go (1)

9-20: Excellent interface design with comprehensive documentation.

The SamplingHandler interface is well-crafted with:

  • Proper use of context for cancellation/timeout handling
  • Correct MCP request/result types from the types package
  • Comprehensive documentation that clearly guides implementers through the expected steps
  • Single responsibility principle with one focused method

The documentation particularly shines in outlining the implementation workflow (validate → approve → select → generate → return).

examples/sampling_server/README.md (1)

1-52: Comprehensive and well-structured documentation.

This README provides excellent coverage of the sampling server example:

  • Clear feature descriptions and tool documentation
  • Practical usage instructions with build commands
  • Helpful implementation details explaining key concepts like EnableSampling() and response routing
  • Testing guidance with the companion client example

The documentation effectively guides users through understanding, building, and testing the sampling functionality.

client/transport/interface.go (3)

34-35: LGTM! Well-defined request handler interface.

The RequestHandler function type follows Go conventions and provides a clean interface for handling incoming requests from servers.


37-45: LGTM! Clean extension for bidirectional communication.

The BidirectionalInterface properly extends the base Interface and provides the necessary method for registering request handlers to support server-initiated requests like sampling.


57-62: LGTM! Appropriate JSON field optimization.

Adding omitempty tags to Result and Error fields prevents sending empty fields in JSON responses, which is correct for JSON-RPC where these fields should only be present when they have meaningful content.

examples/sampling_server/main.go (4)

13-26: LGTM! Proper server initialization and capability setup.

The server initialization correctly enables sampling capability and follows established patterns for MCP server setup.


21-89: LGTM! Well-implemented sampling tool with proper error handling.

The ask_llm tool demonstrates proper usage of the sampling API with:

  • Correct parameter extraction using helper methods
  • Proper sampling request construction
  • Appropriate timeout handling (30 seconds)
  • Good error handling and response formatting

The implementation serves as an excellent example for users implementing sampling functionality.


92-119: LGTM! Simple but informative greeting tool.

The greet tool provides a good contrast to the sampling tool and properly informs users about available sampling functionality.


128-138: LGTM! Robust content extraction helper.

The getTextFromContent function properly handles different content types that might be received in sampling responses, including structured and unstructured formats.

server/sampling_test.go (4)

10-25: LGTM! Good test coverage for enabling sampling.

The test properly verifies the initial state and the effect of enabling sampling on server capabilities.


27-49: LGTM! Proper error handling test.

The test correctly verifies that sampling requests fail when sampling is not enabled, with appropriate error message validation.


51-74: LGTM! Good test for no session scenario.

The test properly validates error handling when no active session is available for sampling requests.


76-107: LGTM! Well-designed mock implementations.

The mock session implementations provide good test doubles for the interfaces, enabling effective unit testing of the sampling functionality.

examples/sampling_client/main.go (4)

14-67: LGTM! Excellent mock sampling handler implementation.

The MockSamplingHandler provides a comprehensive demonstration of how to implement the SamplingHandler interface with:

  • Proper error handling for edge cases
  • Flexible content type handling (TextContent and generic maps)
  • Good logging for debugging
  • Realistic mock response generation

This serves as an excellent template for users implementing real LLM integrations.


69-113: LGTM! Proper client initialization and setup.

The client setup demonstrates correct usage patterns:

  • Proper command-line argument handling
  • Correct transport and client configuration
  • Proper use of WithSamplingHandler option
  • Standard MCP initialization flow

114-144: LGTM! Good tool discovery and testing pattern.

The code properly demonstrates tool listing and basic tool testing, providing good examples for users learning the MCP client API.


146-190: LGTM! Comprehensive sampling functionality demonstration.

The sampling tool tests effectively demonstrate:

  • Different types of sampling requests
  • Proper argument passing
  • Response handling and logging
  • Multiple use cases showing the flexibility of the sampling API

This provides excellent examples for developers implementing sampling clients.

server/sampling.go (2)

28-50: LGTM! Well-structured request handling

The method properly validates preconditions, uses appropriate mutex locking for thread-safe capability checking, and returns descriptive error messages for each failure case.


52-56: LGTM! Clean interface extension

The interface properly extends ClientSession and maintains consistency with the SamplingClient interface method signature.

client/transport/stdio.go (2)

163-169: LGTM! Thread-safe handler registration

The method correctly uses mutex locking to ensure thread-safe assignment of the request handler.


188-194: LGTM! Clean request detection logic

The implementation correctly distinguishes requests from responses by checking for the presence of a method field, maintaining backward compatibility with existing response handling.

client/sampling_test.go (1)

24-87: LGTM! Comprehensive test coverage

The test properly covers both error and success cases using a table-driven approach. Error message validation ensures the correct error is returned.

client/client.go (3)

37-43: LGTM! Clean option pattern implementation

The function follows Go conventions for functional options and includes helpful documentation.


84-88: LGTM! Backward-compatible bidirectional support

The type assertion pattern ensures backward compatibility with transports that don't implement bidirectional communication.


422-431: LGTM! Extensible request routing

The switch statement provides a clean, extensible pattern for handling different request types as they're added.

server/stdio.go (3)

55-70: LGTM! Well-designed concurrent request tracking

The struct properly uses atomic types and mutexes to ensure thread-safe access to shared state. The pending requests map with mutex protection enables safe concurrent request handling.


115-176: LGTM! Robust async request implementation

Excellent implementation with:

  • Proper resource cleanup using defer
  • Context cancellation support
  • Unique request ID generation
  • Safe concurrent access patterns

346-349: LGTM! Clean response routing

The early return pattern cleanly separates sampling response handling from normal message processing.

ezynda3 and others added 2 commits June 29, 2025 23:48
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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 (2)
www/docs/pages/clients/advanced-sampling.mdx (1)

65-76: Add missing log & context imports to keep the snippet compile-ready

The snippet relies on log.Fatalf and context.Background() but the import block is absent. Readers who copy / paste will hit a compile error.

-func main() {
+package main
+
+import (
+    "context"
+    "log"
+
+    "github.com/mark3labs/mcp-go/client"
+)
+
+func main() {
www/docs/pages/servers/advanced-sampling.mdx (1)

16-20: Add fmt to import list

fmt.Sprintf is used inside the tool handler (line 92 & 104) but fmt isn’t imported in this quick-start snippet, so it will not compile.

 import (
     "context"
+    "fmt"
     "github.com/mark3labs/mcp-go/mcp"
     "github.com/mark3labs/mcp-go/server"
 )
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 17ca8df and 976da59.

📒 Files selected for processing (7)
  • server/sampling_test.go (1 hunks)
  • www/docs/pages/clients/advanced-sampling.mdx (1 hunks)
  • www/docs/pages/clients/operations.mdx (1 hunks)
  • www/docs/pages/servers/advanced-sampling.mdx (1 hunks)
  • www/docs/pages/servers/advanced.mdx (1 hunks)
  • www/docs/pages/servers/index.mdx (1 hunks)
  • www/vocs.config.ts (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • www/vocs.config.ts
  • www/docs/pages/servers/index.mdx
  • www/docs/pages/servers/advanced.mdx
  • www/docs/pages/clients/operations.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/sampling_test.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
www/docs/pages/servers/advanced-sampling.mdx (2)
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.

}

// Check if the session supports sampling requests
if samplingSession, ok := session.(SessionWithSampling); ok {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be better if we could find a way to ensure that session is an implementation of SessionWithSampling when EnableSampling is invoked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy