Skip to content

fix(server-stateless): declare the elicitation capability on the streaming-probe request - #383

Merged
pcarleton merged 1 commit into
modelcontextprotocol:mainfrom
logiscapedev:fix/stateless-streaming-probe-elicitation-capability
Jul 27, 2026
Merged

fix(server-stateless): declare the elicitation capability on the streaming-probe request#383
pcarleton merged 1 commit into
modelcontextprotocol:mainfrom
logiscapedev:fix/stateless-streaming-probe-elicitation-capability

Conversation

@logiscapedev

Copy link
Copy Markdown
Contributor

Fixes #382

What

sep-2575-http-server-no-independent-requests-on-stream drives its streaming probe by calling
tools/call test_streaming_elicitation under the scenario's shared validMeta envelope, whose
io.modelcontextprotocol/clientCapabilities is intentionally empty. The fixture legitimately needs
the elicitation capability, so a capability-enforcing server MUST reject the probe with -32021 MissingRequiredClientCapability — the exact behavior sep-2575-server-rejects-undeclared-capability
requires and rewards earlier in the same scenario. Since #372 turned missing-prerequisite skips
into hard failures, one check requires the rejection that makes the other untestable.

This PR declares the capability at the probe site only:

_meta: {
  ...validMeta,
  'io.modelcontextprotocol/clientCapabilities': { elicitation: {} }
}

validMeta itself stays empty — sep-2575-server-rejects-undeclared-capability depends on it.
This matches the intent recorded for this check in #296 ("Call a tool that needs
sampling/elicitation, scan stream frames") and strictly widens coverage: capability-enforcing
servers become testable; servers that ignore capability declarations behave exactly as before.

The sibling probe sep-2575-server-no-log-without-loglevel (test_logging_tool) was audited for
the same latent problem: its fixture keys off _meta.../logLevel, not a client capability, so it
needs no change.

Self-tests (prove it passes and fails)

Two tests added to stateless.test.ts, modeled on the existing mock patterns:

  • Green: a spec-correct, capability-enforcing mock (rejects test_missing_capability without
    sampling and test_streaming_elicitation without elicitation, each with a spec-shaped
    -32021) now passes BOTH formerly-contradictory checks. Against main without the fix this test
    fails exactly as real servers do: the stream check reads
    FAILURE — Not testable: the 'test_streaming_elicitation' call was rejected (code -32021).
  • Guard: a server that rejects the streaming probe despite the declared capability still
    produces the red untestable outcome, not a vacuous SUCCESS.

npm test 333/333, npm run check clean.

Real-SDK evidence (per CONTRIBUTING)

Run against the PHP SDK (logiscape/mcp-sdk-php v2 main), whose everything-server enforces
per-request capability declaration:

  • Before: 27/28 — sep-2575-http-server-no-independent-requests-on-stream fails:
    Not testable: the 'test_streaming_elicitation' call was rejected (code -32021), so the response stream could not be exercised
  • After: 28/28.

No regression against this repo's own example server (examples/servers/typescript): 30/30
before and after (it does not enforce capabilities on this fixture, so the added declaration is
inert there).

Note on sequencing

Draft PR #351 hoists/shares this same probe stream between checks; this fix is written against
current main and is a one-expression change at the probe site, so whichever lands first, the
other rebases trivially. Happy to coordinate.

🤖 Generated with Claude Code

@pcarleton

Copy link
Copy Markdown
Member

thanks for this @logiscapedev !

@pcarleton
pcarleton enabled auto-merge (squash) July 27, 2026 10:45
@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

npx https://pkg.pr.new/@modelcontextprotocol/conformance@383

commit: 28b4a4c

@pcarleton
pcarleton merged commit a989655 into modelcontextprotocol:main Jul 27, 2026
4 checks passed
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.

server-stateless: sep-2575-http-server-no-independent-requests-on-stream probe never declares the elicitation capability its own fixture requires

2 participants