modelcontextprotocol / modelcontextprotocol/conformance
request-state-complete accepts tool-error results and completions missing its documented state-ok marker
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 127
- Forks
- 101
- Avg merge
- 6d 1h
- Merged PRs (30d)
- 7
Description
Scope
While examining the concrete prerequisite problem in #440, I found a separate round-2 false-positive in InputRequiredResultRequestStateScenario. This case uses a non-empty, correctly keyed inputRequests map, so it does not depend on #440's manufactured "undefined" key. Credit for that original issue remains with its reporter.
Inspected main commit: 7169291ec0b68eb370fddcd9947313ab0d5e4156.
The fixture description requires round 2 to validate echoed state and return text containing state-ok. The check only rejects a JSON-RPC error, an absent result, or resultType: "input_required". It never checks the tool-result isError flag or the documented marker.
Executed local probe
I copied this scenario's run body into an isolated TypeScript wrapper, transpiled it with TypeScript 5.8.3, and executed it on Node 22.16.0. sendRpc was a controlled two-response stub; the type guards and mock-elicitation logic matched the pinned helper. Round 1 always returned a non-empty confirm elicitation and requestState: "s-1".
| Round-2 response | Observed sep-2322-request-state-complete |
Expected under this fixture's stated contract |
|---|---|---|
complete, text state-ok |
SUCCESS | SUCCESS |
complete, text ordinary completion |
SUCCESS | FAILURE: missing fixture marker |
complete, isError: true, text state rejected |
SUCCESS | FAILURE: tool error |
complete, isError: true, text state-ok, but execution failed |
SUCCESS | FAILURE: marker must not override tool error |
| JSON-RPC error | FAILURE | FAILURE |
| another input-required result | FAILURE | FAILURE |
| no result | FAILURE | FAILURE |
Execution boundary: this is an isolated execution of the copied check body, not an upstream CLI run, HTTP transport test, or real-SDK conformance result. A local candidate adding both result predicates produced the expected outcomes in all seven cases. No upstream patch is asserted tested or ready to merge.
Minimal predicate reproduction
This can also be seen without any SDK dependencies; save as probe.cjs and run node probe.cjs:
const assert = require('node:assert/strict');
// Logic of the pinned helper and successful-result branch, types removed.
const isCompleteResult = r => !!r && r.resultType !== 'input_required';
function currentCheck(r2) {
const result = r2.result;
const errors = [];
if (r2.error) errors.push('JSON-RPC error');
else if (!result) errors.push('No result');
else if (!isCompleteResult(result)) errors.push('Not complete');
return errors.length === 0 ? 'SUCCESS' : 'FAILURE';
}
for (const result of [
{resultType:'complete', content:[{type:'text', text:'ordinary completion'}]},
{resultType:'complete', isError:true, content:[{type:'text', text:'state rejected'}]}
]) {
assert.equal(currentCheck({result}), 'SUCCESS');
console.log(currentCheck({result}));
}
Both print SUCCESS, despite violating the scenario's documented successful-completion requirement.
Suggested regression scope
Extend the existing MRTR negative-test/fixture path, rather than adding another runner: exercise both kinds of erroneous completion, keep a state-ok success control, and retain the JSON-RPC-error/input-required controls. Keep the same check ID for pass and fail. The marker requirement is fixture-specific, not a new normative MCP requirement for all servers. Checking a marker also cannot prove genuine state validation by itself; the separate tampered-state scenario remains necessary.
This does not show that a broken implementation passes the entire suite. It shows that this one named check can report successful state validation on these completions. Searched existing issues for state-ok and request-state plus isError; no matching report was returned.
Prepared by Youngseok Oh (@YS-OH-CORE) with Zero (ChatGPT); AI-assisted source analysis and local probe. Public synthetic inputs only.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the round-2 check in src/scenarios/server/input-required-result.ts and the helper in src/scenarios/server/input-required-result-helpers.ts. Run the existing MRTR negative-test or fixture path, preserving the JSON-RPC-error and input-required cases. Done means erroneous complete results fail, a complete result containing state-ok passes, and the same check ID is retained.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100