Repository navigation
Conversation
The mcptest.Server helper previously had no way to test tools that call server.RequestSampling or server.RequestElicitation, because the underlying client was created without sampling/elicitation options and the stdio transport request-handler was never wired up. This change: - Adds SetSamplingHandler(client.SamplingHandler) to mcptest.Server - Adds SetElicitationHandler(client.ElicitationHandler) to mcptest.Server - Passes the handlers as client.ClientOption to client.NewClient - Uses client.Start() instead of transport.Start() so the bidirectional request handler (needed for server-to-client sampling/elicitation calls over stdio) is registered before the Initialize handshake - Automatically calls mcpServer.EnableSampling() when a sampling handler is set, removing boilerplate from callers Two tests are added in mcptest_sampling_elicitation_test.go covering both paths end-to-end through the real stdio transport.
|
Connected to Huly®: MCP_G-466 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe PR extends ChangesSampling and Elicitation Handler Support
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
ezynda3
left a comment
There was a problem hiding this comment.
PR Review: #902 — feat(mcptest): add sampling and elicitation handler support
Verdict: PASS ✅
Security (Step 2 + reviewer)
- No findings. Static scan was clean across secrets, exec, SQL, gob, unsafe, TLS, math/rand, panic, and debug leftovers.
Logic errors
- None identified.
Regressions vs base (Step 3)
go build ./...— clean on both base and head.go vet ./...— clean on both.go test ./mcptest/... -race -count=1— clean; both new tests (TestServerWithSamplingHandler,TestServerWithElicitationHandler) pass under-race.golangci-lint run ./mcptest/...— 0 issues.gofmt -landgo mod tidy— clean.- One flake observed in
server.TestMCPServer_HybridModeDetectionon the first full-racerun on HEAD; it does not reproduce in isolation on either base or head (3/3 passes), and the test does not touch any code modified by this PR. Treating as pre-existing flake, not a regression.
Go idiom & style
- Exported
SetSamplingHandler/SetElicitationHandlerhave godocs starting with the identifier name. ✅ - Error wrapping uses
%w(fmt.Errorf("client.Start(): %w", err)). ✅ - Goroutine capture comment correctly notes why
samplingHandleris snapshotted before thego func()(it is read inside the goroutine to gateEnableSampling()). The elicitation handler is only read on the main goroutine, so capture is not required for it; capturing both for symmetry would be marginally cleaner but is not required. - Test doubles'
callCountfields are mutated without sync — fine because each test issues exactly one call, but worth noting if these helpers ever get reused concurrently.
Suggestions (non-blocking)
- Consider making
SetSamplingHandler/SetElicitationHandlerpanic (or return an error) if called afterStart()to fail loudly rather than silently being ignored. - Add a negative-path test where the sampling handler returns an error or the elicitation handler declines/cancels, to cover the error branches in
RequestSampling/RequestElicitationflows from tests' perspective. - Switching from
transport.Start()toclient.Start()is the right call —client.Start()is idempotent on the transport and is what wiresSetRequestHandlerfor theBidirectionalInterface, which is exactly what sampling/elicitation need. The PR description accurately describes this.
Summary
Small, well-scoped, well-tested addition that fills a real gap in mcptest (no way to exercise tools that call back into the client). Implementation is correct, idiomatic, and all CI checks plus local race tests pass.
|
Just checking in on this one — CI is green (tests, lint, golangci-lint, verify-codegen) and CodeRabbit had no blocking feedback. Glad to adjust anything the maintainers would like. Thanks for the reviews! |
The
mcptestpackage is very convenient for testing MCP servers — especially tools, prompts, resources, and hooks — without standing up a real transport. However, it currently has no way to test tools that call back into the client via sampling (server.RequestSampling) or elicitation (server.RequestElicitation). Anyone writing such a tool today has to wire upInProcessTransport+InProcessSessionby hand, which is considerably more boilerplate.What this PR does
Adds two new methods to
mcptest.Server:When a handler is registered:
client.ClientOptiontoclient.NewClient, so the capability is advertised in theinitializehandshake.client.Start()is called instead oftransport.Start()— this is the key fix:client.Start()wires the bidirectionalSetRequestHandleron the underlying*transport.Stdioso that server→client JSON-RPC requests (sampling, elicitation) are dispatched to the handler rather than being dropped with No request handler configured.mcpServer.EnableSampling()is called automatically inside the server goroutine, so callers do not need to add it viaAddServerOptions.Changes
mcptest/mcptest.goclient.Start()instead oftransport.Start(), autoEnableSampling()mcptest/mcptest_sampling_elicitation_test.goTests
All pre-existing
mcptesttests continue to pass. Theclientandclient/transportpackages time out in this environment (pre-existing onmainas well);server,mcp,e2e,mcptest, andtracingall pass.Summary by CodeRabbit
Release Notes
New Features
Tests