Following up on #439 item 3 — I went to look at that one guard and found a
round-2 consequence that issue doesn't cover.
InputRequiredResult.inputRequests is optional (required: ["resultType"] in the
draft schema), and sep-2322.yaml states the rule as "at least one of
inputRequests or requestState". So a server answering
{ "resultType": "input_required", "requestState": "s-1", "inputRequests": {} }
is conformant, and the round-1 checks are right to pass it. But five round-2 sites
then take the first key of that map without checking it exists:
const inputKey = Object.keys(r1Result.inputRequests!)[0]; // undefined
// ...
inputResponses: { [inputKey]: mockElicitResponse({ ok: true }) }
A computed key stringifies, so the harness puts the literal string "undefined" on
the wire.
Repro
Against a probe server returning the result above for every MRTR tool and
prompts/get, with requestState rotating so round 2 is reachable:
node dist/index.js server --url http://localhost:PORT/mcp \
--scenario input-required-result-request-state --spec-version 2026-07-28
The probe logged the inputResponses keys it received across four scenarios:
tools/call test_input_required_result_request_state -> ["undefined"]
tools/call test_input_required_result_multi_round -> ["undefined"]
tools/call test_input_required_result_multi_round -> ["undefined"]
prompts/get test_input_required_result_prompt -> ["undefined"]
tools/call test_input_required_result_tampered_state -> ["undefined"]
Sites: :539, :865, :908, :1095, :1337. The two equivalents at
:269 and :405 are unreachable here — their round-1 arms use
Object.keys(...)[0] behind a !key guard that already failed the scenario.
Why it matters
The round-2 check then fails, and the report attributes that to the server:
[sep-2322-request-state-incomplete] SUCCESS Server returns InputRequiredResult with both inputRequests and requestState
[sep-2322-request-state-complete ] FAILURE Server validates echoed requestState and returns complete result
[wire-schema-valid ] SUCCESS Every JSON-RPC message the implementation sent is valid ...
wire-schema-valid passes because inputResponses keys are unconstrained, so
nothing else catches it either.
Suggested direction
Gate round 2 on actually having a key, and report the prerequisite rather than
sending a request that can't be answered — the convention #372 established for
missing prerequisites. Each of the five sites is two lines; happy to send a PR.
negative-mrtr.test.ts plus sep-2322-mrtr-broken-server already give a place to
assert it, so this can carry a regression test without new harness plumbing.
Following up on #439 item 3 — I went to look at that one guard and found a
round-2 consequence that issue doesn't cover.
InputRequiredResult.inputRequestsis optional (required: ["resultType"]in thedraft schema), and
sep-2322.yamlstates the rule as "at least one ofinputRequestsorrequestState". So a server answering{ "resultType": "input_required", "requestState": "s-1", "inputRequests": {} }is conformant, and the round-1 checks are right to pass it. But five round-2 sites
then take the first key of that map without checking it exists:
A computed key stringifies, so the harness puts the literal string
"undefined"onthe wire.
Repro
Against a probe server returning the result above for every MRTR tool and
prompts/get, withrequestStaterotating so round 2 is reachable:The probe logged the
inputResponseskeys it received across four scenarios:Sites:
:539,:865,:908,:1095,:1337. The two equivalents at:269and:405are unreachable here — their round-1 arms useObject.keys(...)[0]behind a!keyguard that already failed the scenario.Why it matters
The round-2 check then fails, and the report attributes that to the server:
wire-schema-validpasses becauseinputResponseskeys are unconstrained, sonothing else catches it either.
Suggested direction
Gate round 2 on actually having a key, and report the prerequisite rather than
sending a request that can't be answered — the convention #372 established for
missing prerequisites. Each of the five sites is two lines; happy to send a PR.
negative-mrtr.test.tsplussep-2322-mrtr-broken-serveralready give a place toassert it, so this can carry a regression test without new harness plumbing.