Skip to content

Prevent discovery probe timeouts in controlled test connections - #1946

Merged
tarekgh merged 1 commit into
modelcontextprotocol:mainfrom
tarekgh:fix/test-discovery-timeouts
Oct 22, 2026
Merged

tarekgh merged 1 commit into
modelcontextprotocol:mainfrom
tarekgh:fix/test-discovery-timeouts

Conversation

@tarekgh

@tarekgh tarekgh commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Extend the test-only discovery timeout protection from #1943 to the remaining affected controlled-server connections.

  • Add a shared TestMcpClient helper that disables the separate discovery probe timer while retaining the 60-second overall initialization deadline. Explicitly supplied options remain unchanged.
  • Apply the defaults across HTTP/MRTR, Tasks, OAuth, hybrid session-mode, response-driven HTTP fallback, direct pipe/stdio, and AOT test connections. Apply defaults before test configuration callbacks so explicit overrides still work.
  • Pin the legacy-only elicitation defaults mock to its supported protocol version and reject unexpected requests instead of silently waiting for discovery to time out.
  • Preserve dedicated timeout tests, silent-server fallback coverage, external conformance-client behavior, and production SDK defaults. Document the helper's scope in the contributor guide.

Why

A controlled server can take longer than the default five-second discovery probe budget to respond on a busy CI runner. The client then attempts legacy fallback even though the server supports the modern protocol. For tests pinned to the modern version, this surfaces as a misleading unsupported-protocol error before the behavior under test executes.

This is the connection failure observed in MapMcpStatelessTests.Mrtr_ConcurrentThreeInputs_ResolvedSimultaneously on #1934. The existing fix covered only selected helpers; other direct and shared connection paths retained the short probe budget.

Validation

  • Release solution build: zero warnings and zero errors.
  • Full non-manual Release test suite: 11,416 passed, 397 skipped, zero failures across all configured target frameworks.
  • Added fake-clock coverage for delayed discovery, the overall initialization deadline, and explicit probe-timeout overrides. Confirmed the delayed-discovery regression fails with the original defaults and passes with the fix.
  • Managed AOT compatibility app: passed. Native AOT publishing could not be verified locally because NuGet TLS failures prevented downloading the required runtime packs; CI must cover native publishing.

@jeffhandley jeffhandley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice! Looks good to me. The only other thing I would suggest is setting TestConstants.DefaultTimeout to be a property getter that would respect an environment variable to override the 60s hard-coded value, but I don't think we need to introduce that unless we see any further flakiness where 60s isn't always enough in CI, but gosh I hope it is.

@tarekgh tarekgh mentioned this pull request Oct 22, 2026
5 tasks done
@tarekgh

tarekgh commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Nice! Looks good to me. The only other thing I would suggest is setting TestConstants.DefaultTimeout to be a property getter that would respect an environment variable to override the 60s hard-coded value, but I don't think we need to introduce that unless we see any further flakiness where 60s isn't always enough in CI, but gosh I hope it is.

Thanks, this is a good idea, let's wait to see any scenario need it and I'll be happy to add it.

@tarekgh
tarekgh merged commit 2bd715b into modelcontextprotocol:main Oct 22, 2026
11 checks passed
girishkvs added a commit to girishkvs/csharp-sdk that referenced this pull request Oct 22, 2026
modelcontextprotocol#1943 and modelcontextprotocol#1946 give stdio test_server clients an unbounded server/discover
probe when a test passes no options, and leave options a test passes
unchanged. Sampling_Stdio passes options for its sampling handler without
pinning a protocol version, so its test_server case still used the
5-second probe and could fall back to initialize while the discover answer
was on its way; the server then rejects initialize. Start its test_server
options from TestMcpClient.CreateOptions(), as CONTRIBUTING.md asks; the
everything server keeps the default probe.
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.

3 participants