modelcontextprotocol / modelcontextprotocol/conformance

input-required-result: harness sends the literal string `"undefined"` as an inputResponses key when round 1 names no input requests

Open
#440 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
127
Forks
101
Avg merge
6d 1h
Merged PRs (30d)
7

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/scenarios/server/input-required-result.ts at the round-2 sites on lines 539, 865, 908, 1095, and 1337, then run the input-required-result-request-state scenario against the described probe server. Use negative-mrtr.test.ts and sep-2322-mrtr-broken-server for the regression assertion. Done means round 2 reports the missing prerequisite instead of sending an inputResponses key named "undefined".

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
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.